void mips_malta_init(MachineState *machine)

{

    ram_addr_t ram_size = machine->ram_size;

    ram_addr_t ram_low_size;

    const char *cpu_model = machine->cpu_model;

    const char *kernel_filename = machine->kernel_filename;

    const char *kernel_cmdline = machine->kernel_cmdline;

    const char *initrd_filename = machine->initrd_filename;

    char *filename;

    pflash_t *fl;

    MemoryRegion *system_memory = get_system_memory();

    MemoryRegion *ram_high = g_new(MemoryRegion, 1);

    MemoryRegion *ram_low_preio = g_new(MemoryRegion, 1);

    MemoryRegion *ram_low_postio;

    MemoryRegion *bios, *bios_copy = g_new(MemoryRegion, 1);

    target_long bios_size = FLASH_SIZE;

    const size_t smbus_eeprom_size = 8 * 256;

    uint8_t *smbus_eeprom_buf = g_malloc0(smbus_eeprom_size);

    int64_t kernel_entry, bootloader_run_addr;

    PCIBus *pci_bus;

    ISABus *isa_bus;

    MIPSCPU *cpu;

    CPUMIPSState *env;

    qemu_irq *isa_irq;

    int piix4_devfn;

    I2CBus *smbus;

    int i;

    DriveInfo *dinfo;

    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];

    DriveInfo *fd[MAX_FD];

    int fl_idx = 0;

    int fl_sectors = bios_size >> 16;

    int be;

    DeviceState *dev = qdev_create(NULL, TYPE_MIPS_MALTA);

    MaltaState *s = MIPS_MALTA(dev);

    /* The whole address space decoded by the GT-64120A doesn't generate

       exception when accessing invalid memory. Create an empty slot to

       emulate this feature. */

    empty_slot_init(0, 0x20000000);

    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_new(label, "null", NULL);

        }

    }

    /* init CPUs */

    if (cpu_model == NULL) {

#ifdef TARGET_MIPS64

        cpu_model = "20Kc";

#else

        cpu_model = "24Kf";

#endif

    }

    for (i = 0; i < smp_cpus; i++) {

        cpu = cpu_mips_init(cpu_model);

        if (cpu == NULL) {

            fprintf(stderr, "Unable to find CPU definition\n");

            exit(1);

        }

        env = &cpu->env;

        /* Init internal devices */

        cpu_mips_irq_init_cpu(env);

        cpu_mips_clock_init(env);

        qemu_register_reset(main_cpu_reset, cpu);

    }

    cpu = MIPS_CPU(first_cpu);

    env = &cpu->env;

    /* allocate RAM */

    if (ram_size > (2048u << 20)) {

        fprintf(stderr,

                "qemu: Too much memory for this machine: %d MB, maximum 2048 MB\n",

                ((unsigned int)ram_size / (1 << 20)));

        exit(1);

    }

    /* register RAM at high address where it is undisturbed by IO */

    memory_region_allocate_system_memory(ram_high, NULL, "mips_malta.ram",

                                         ram_size);

    memory_region_add_subregion(system_memory, 0x80000000, ram_high);

    /* alias for pre IO hole access */

    memory_region_init_alias(ram_low_preio, NULL, "mips_malta_low_preio.ram",

                             ram_high, 0, MIN(ram_size, (256 << 20)));

    memory_region_add_subregion(system_memory, 0, ram_low_preio);

    /* alias for post IO hole access, if there is enough RAM */

    if (ram_size > (512 << 20)) {

        ram_low_postio = g_new(MemoryRegion, 1);

        memory_region_init_alias(ram_low_postio, NULL,

                                 "mips_malta_low_postio.ram",

                                 ram_high, 512 << 20,

                                 ram_size - (512 << 20));

        memory_region_add_subregion(system_memory, 512 << 20, ram_low_postio);

    }

    /* generate SPD EEPROM data */

    generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size);

    generate_eeprom_serial(&smbus_eeprom_buf[6 * 256]);

#ifdef TARGET_WORDS_BIGENDIAN

    be = 1;

#else

    be = 0;

#endif

    /* FPGA */

    /* The CBUS UART is attached to the MIPS CPU INT2 pin, ie interrupt 4 */

    malta_fpga_init(system_memory, FPGA_ADDRESS, env->irq[4], serial_hds[2]);

    /* Load firmware in flash / BIOS. */

    dinfo = drive_get(IF_PFLASH, 0, fl_idx);

#ifdef DEBUG_BOARD_INIT

    if (dinfo) {

        printf("Register parallel flash %d size " TARGET_FMT_lx " at "

               "addr %08llx '%s' %x\n",

               fl_idx, bios_size, FLASH_ADDRESS,

               blk_name(dinfo->bdrv), fl_sectors);

    }

#endif

    fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios",

                               BIOS_SIZE,

                               dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,

                               65536, fl_sectors,

                               4, 0x0000, 0x0000, 0x0000, 0x0000, be);

    bios = pflash_cfi01_get_memory(fl);

    fl_idx++;

    if (kernel_filename) {

        ram_low_size = MIN(ram_size, 256 << 20);

        /* For KVM we reserve 1MB of RAM for running bootloader */

        if (kvm_enabled()) {

            ram_low_size -= 0x100000;

            bootloader_run_addr = 0x40000000 + ram_low_size;

        } else {

            bootloader_run_addr = 0xbfc00000;

        }

        /* Write a small bootloader to the flash location. */

        loaderparams.ram_size = ram_size;

        loaderparams.ram_low_size = ram_low_size;

        loaderparams.kernel_filename = kernel_filename;

        loaderparams.kernel_cmdline = kernel_cmdline;

        loaderparams.initrd_filename = initrd_filename;

        kernel_entry = load_kernel();

        write_bootloader(memory_region_get_ram_ptr(bios),

                         bootloader_run_addr, kernel_entry);

        if (kvm_enabled()) {

            /* Write the bootloader code @ the end of RAM, 1MB reserved */

            write_bootloader(memory_region_get_ram_ptr(ram_low_preio) +

                                    ram_low_size,

                             bootloader_run_addr, kernel_entry);

        }

    } else {

        /* The flash region isn't executable from a KVM guest */

        if (kvm_enabled()) {

            error_report("KVM enabled but no -kernel argument was specified. "

                         "Booting from flash is not supported with KVM.");

            exit(1);

        }

        /* Load firmware from flash. */

        if (!dinfo) {

            /* Load a BIOS 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, FLASH_ADDRESS,

                                                BIOS_SIZE);

                g_free(filename);

            } else {

                bios_size = -1;

            }

            if ((bios_size < 0 || bios_size > BIOS_SIZE) &&

                !kernel_filename && !qtest_enabled()) {

                error_report("Could not load MIPS bios '%s', and no "

                             "-kernel argument was specified", bios_name);

                exit(1);

            }

        }

        /* In little endian mode the 32bit words in the bios are swapped,

           a neat trick which allows bi-endian firmware. */

#ifndef TARGET_WORDS_BIGENDIAN

        {

            uint32_t *end, *addr = rom_ptr(FLASH_ADDRESS);

            if (!addr) {

                addr = memory_region_get_ram_ptr(bios);

            }

            end = (void *)addr + MIN(bios_size, 0x3e0000);

            while (addr < end) {

                bswap32s(addr);

                addr++;

            }

        }

#endif

    }

    /*

     * Map the BIOS at a 2nd physical location, as on the real board.

     * Copy it so that we can patch in the MIPS revision, which cannot be

     * handled by an overlapping region as the resulting ROM code subpage

     * regions are not executable.

     */

    memory_region_init_ram(bios_copy, NULL, "bios.1fc", BIOS_SIZE,

                           &error_fatal);

    if (!rom_copy(memory_region_get_ram_ptr(bios_copy),

                  FLASH_ADDRESS, BIOS_SIZE)) {

        memcpy(memory_region_get_ram_ptr(bios_copy),

               memory_region_get_ram_ptr(bios), BIOS_SIZE);

    }

    memory_region_set_readonly(bios_copy, true);

    memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_copy);

    /* Board ID = 0x420 (Malta Board with CoreLV) */

    stl_p(memory_region_get_ram_ptr(bios_copy) + 0x10, 0x00000420);

    /* Init internal devices */

    cpu_mips_irq_init_cpu(env);

    cpu_mips_clock_init(env);

    /*

     * 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(isa_irq);

    /* Southbridge */

    ide_drive_get(hd, ARRAY_SIZE(hd));

    piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);

    /* Interrupt controller */

    /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */

    s->i8259 = i8259_init(isa_bus, env->irq[2]);

    isa_bus_irqs(isa_bus, s->i8259);

    pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);

    pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci");

    smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,

                          isa_get_irq(NULL, 9), NULL, 0, NULL);

    smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size);

    g_free(smbus_eeprom_buf);

    pit = pit_init(isa_bus, 0x40, 0, NULL);

    DMA_init(isa_bus, 0);

    /* Super I/O */

    isa_create_simple(isa_bus, "i8042");

    rtc_init(isa_bus, 2000, NULL);

    serial_hds_isa_init(isa_bus, 2);

    parallel_hds_isa_init(isa_bus, 1);

    for(i = 0; i < MAX_FD; i++) {

        fd[i] = drive_get(IF_FLOPPY, 0, i);

    }

    fdctrl_init_isa(isa_bus, fd);

    /* Network card */

    network_init(pci_bus);

    /* Optional PCI video card */

    pci_vga_init(pci_bus);

}


static void video_refresh(void *opaque, double *remaining_time)

{

    VideoState *is = opaque;

    VideoPicture *vp;

    double time;

    SubPicture *sp, *sp2;

    if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)

        check_external_clock_speed(is);

    if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {

        time = av_gettime() / 1000000.0;

        if (is->force_refresh || is->last_vis_time + rdftspeed < time) {

            video_display(is);

            is->last_vis_time = time;

        }

        *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);

    }

    if (is->video_st) {

        int redisplay = 0;

        if (is->force_refresh)

            redisplay = pictq_prev_picture(is);

retry:

        if (is->pictq_size == 0) {

            SDL_LockMutex(is->pictq_mutex);

            if (is->frame_last_dropped_pts != AV_NOPTS_VALUE && is->frame_last_dropped_pts > is->frame_last_pts) {

                update_video_pts(is, is->frame_last_dropped_pts, is->frame_last_dropped_pos, is->frame_last_dropped_serial);

                is->frame_last_dropped_pts = AV_NOPTS_VALUE;

            }

            SDL_UnlockMutex(is->pictq_mutex);

            // nothing to do, no picture to display in the queue

        } else {

            double last_duration, duration, delay;

            /* dequeue the picture */

            vp = &is->pictq[is->pictq_rindex];

            if (vp->serial != is->videoq.serial) {

                pictq_next_picture(is);

                redisplay = 0;

                goto retry;

            }

            if (is->paused)

                goto display;

            /* compute nominal last_duration */

            last_duration = vp->pts - is->frame_last_pts;

            if (!isnan(last_duration) && last_duration > 0 && last_duration < is->max_frame_duration) {

                /* if duration of the last frame was sane, update last_duration in video state */

                is->frame_last_duration = last_duration;

            }

            if (redisplay)

                delay = 0.0;

            else

                delay = compute_target_delay(is->frame_last_duration, is);

            time= av_gettime()/1000000.0;

            if (time < is->frame_timer + delay && !redisplay) {

                *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);

                return;

            }

            is->frame_timer += delay;

            if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)

                is->frame_timer = time;

            SDL_LockMutex(is->pictq_mutex);

            if (!redisplay && !isnan(vp->pts))

                update_video_pts(is, vp->pts, vp->pos, vp->serial);

            SDL_UnlockMutex(is->pictq_mutex);

            if (is->pictq_size > 1) {

                VideoPicture *nextvp = &is->pictq[(is->pictq_rindex + 1) % VIDEO_PICTURE_QUEUE_SIZE];

                duration = nextvp->pts - vp->pts;

                if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){

                    if (!redisplay)

                        is->frame_drops_late++;

                    pictq_next_picture(is);

                    redisplay = 0;

                    goto retry;

                }

            }

            if (is->subtitle_st) {

                    while (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 (sp->serial != is->subtitleq.serial

                                || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))

                                || (sp2 && is->vidclk.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);

                        } else {

                            break;

                        }

                    }

            }

display:

            /* display picture */

            if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)

                video_display(is);

            pictq_next_picture(is);

            if (is->step && !is->paused)

                stream_toggle_pause(is);

        }

    }

    is->force_refresh = 0;

    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_clock(&is->audclk) - get_clock(&is->vidclk);

            else if (is->video_st)

                av_diff = get_master_clock(is) - get_clock(&is->vidclk);

            else if (is->audio_st)

                av_diff = get_master_clock(is) - get_clock(&is->audclk);

            av_log(NULL, AV_LOG_INFO,

                   "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64"   \r",

                   get_master_clock(is),

                   (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : "   ")),

                   av_diff,

                   is->frame_drops_early + is->frame_drops_late,

                   aqsize / 1024,

                   vqsize / 1024,

                   sqsize,

                   is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,

                   is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);

            fflush(stdout);

            last_time = cur_time;

        }

    }

}


static void extrapolate_isf(float out[LP_ORDER_16k], float isf[LP_ORDER])

{

    float diff_isf[LP_ORDER - 2], diff_mean;

    float *diff_hi = diff_isf - LP_ORDER + 1; // diff array for extrapolated indexes

    float corr_lag[3];

    float est, scale;

    int i, i_max_corr;

    memcpy(out, isf, (LP_ORDER - 1) * sizeof(float));

    out[LP_ORDER_16k - 1] = isf[LP_ORDER - 1];

    /* Calculate the difference vector */

    for (i = 0; i < LP_ORDER - 2; i++)

        diff_isf[i] = isf[i + 1] - isf[i];

    diff_mean = 0.0;

    for (i = 2; i < LP_ORDER - 2; i++)

        diff_mean += diff_isf[i] * (1.0f / (LP_ORDER - 4));

    /* Find which is the maximum autocorrelation */

    i_max_corr = 0;

    for (i = 0; i < 3; i++) {

        corr_lag[i] = auto_correlation(diff_isf, diff_mean, i + 2);

        if (corr_lag[i] > corr_lag[i_max_corr])

            i_max_corr = i;

    }

    i_max_corr++;

    for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++)

        out[i] = isf[i - 1] + isf[i - 1 - i_max_corr]

                            - isf[i - 2 - i_max_corr];

    /* Calculate an estimate for ISF(18) and scale ISF based on the error */

    est   = 7965 + (out[2] - out[3] - out[4]) / 6.0;

    scale = 0.5 * (FFMIN(est, 7600) - out[LP_ORDER - 2]) /

            (out[LP_ORDER_16k - 2] - out[LP_ORDER - 2]);

    for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++)

        diff_hi[i] = scale * (out[i] - out[i - 1]);

    /* Stability insurance */

    for (i = LP_ORDER; i < LP_ORDER_16k - 1; i++)

        if (diff_hi[i] + diff_hi[i - 1] < 5.0) {

            if (diff_hi[i] > diff_hi[i - 1]) {

                diff_hi[i - 1] = 5.0 - diff_hi[i];

            } else

                diff_hi[i] = 5.0 - diff_hi[i - 1];

        }

    for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++)

        out[i] = out[i - 1] + diff_hi[i] * (1.0f / (1 << 15));

    /* Scale the ISF vector for 16000 Hz */

    for (i = 0; i < LP_ORDER_16k - 1; i++)

        out[i] *= 0.8;

}


static int get_video_private_data(struct VideoFile *vf, AVCodecContext *codec)

{

    AVIOContext *io = NULL;

    uint16_t sps_size, pps_size;

    int err = AVERROR(EINVAL);

    if (codec->codec_id == AV_CODEC_ID_VC1)

        return get_private_data(vf, codec);

    avio_open_dyn_buf(&io);

    if (codec->extradata_size < 11 || codec->extradata[0] != 1)

        goto fail;

    sps_size = AV_RB16(&codec->extradata[6]);

    if (11 + sps_size > codec->extradata_size)

        goto fail;

    avio_wb32(io, 0x00000001);

    avio_write(io, &codec->extradata[8], sps_size);

    pps_size = AV_RB16(&codec->extradata[9 + sps_size]);

    if (11 + sps_size + pps_size > codec->extradata_size)

        goto fail;

    avio_wb32(io, 0x00000001);

    avio_write(io, &codec->extradata[11 + sps_size], pps_size);

    err = 0;

fail:

    vf->codec_private_size = avio_close_dyn_buf(io, &vf->codec_private);

    return err;

}


static void FUNCC(pred8x8l_horizontal)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride)

{

    pixel *src = (pixel*)p_src;

    int stride = p_stride>>(sizeof(pixel)-1);

    PREDICT_8x8_LOAD_LEFT;

#define ROW(y) ((pixel4*)(src+y*stride))[0] =\

               ((pixel4*)(src+y*stride))[1] = PIXEL_SPLAT_X4(l##y)

    ROW(0); ROW(1); ROW(2); ROW(3); ROW(4); ROW(5); ROW(6); ROW(7);

#undef ROW

}


static int dca_parse_params(DCAParseContext *pc1, const uint8_t *buf,

                            int buf_size, int *duration, int *sample_rate,

                            int *profile)

{

    DCAExssAsset *asset = &pc1->exss.assets[0];

    GetBitContext gb;

    DCACoreFrameHeader h;

    uint8_t hdr[DCA_CORE_FRAME_HEADER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE] = { 0 };

    int ret, frame_size;

    if (buf_size < DCA_CORE_FRAME_HEADER_SIZE)

        return AVERROR_INVALIDDATA;

    if (AV_RB32(buf) == DCA_SYNCWORD_SUBSTREAM) {

        if ((ret = ff_dca_exss_parse(&pc1->exss, buf, buf_size)) < 0)

            return ret;

        if (asset->extension_mask & DCA_EXSS_LBR) {

            if ((ret = init_get_bits8(&gb, buf + asset->lbr_offset, asset->lbr_size)) < 0)

                return ret;

            if (get_bits_long(&gb, 32) != DCA_SYNCWORD_LBR)

                return AVERROR_INVALIDDATA;

            switch (get_bits(&gb, 8)) {

            case DCA_LBR_HEADER_DECODER_INIT:

                pc1->sr_code = get_bits(&gb, 8);

            case DCA_LBR_HEADER_SYNC_ONLY:

                break;

            default:

                return AVERROR_INVALIDDATA;

            }

            if (pc1->sr_code >= FF_ARRAY_ELEMS(ff_dca_sampling_freqs))

                return AVERROR_INVALIDDATA;

            *sample_rate = ff_dca_sampling_freqs[pc1->sr_code];

            *duration = 1024 << ff_dca_freq_ranges[pc1->sr_code];

            *profile = FF_PROFILE_DTS_EXPRESS;

            return 0;

        }

        if (asset->extension_mask & DCA_EXSS_XLL) {

            int nsamples_log2;

            if ((ret = init_get_bits8(&gb, buf + asset->xll_offset, asset->xll_size)) < 0)

                return ret;

            if (get_bits_long(&gb, 32) != DCA_SYNCWORD_XLL)

                return AVERROR_INVALIDDATA;

            if (get_bits(&gb, 4))

                return AVERROR_INVALIDDATA;

            skip_bits(&gb, 8);

            skip_bits_long(&gb, get_bits(&gb, 5) + 1);

            skip_bits(&gb, 4);

            nsamples_log2 = get_bits(&gb, 4) + get_bits(&gb, 4);

            if (nsamples_log2 > 24)

                return AVERROR_INVALIDDATA;

            *sample_rate = asset->max_sample_rate;

            *duration = (1 + (*sample_rate > 96000)) << nsamples_log2;

            *profile = FF_PROFILE_DTS_HD_MA;

            return 0;

        }

        return AVERROR_INVALIDDATA;

    }

    if ((ret = avpriv_dca_convert_bitstream(buf, DCA_CORE_FRAME_HEADER_SIZE,

                                            hdr, DCA_CORE_FRAME_HEADER_SIZE)) < 0)

        return ret;

    if ((ret = init_get_bits8(&gb, hdr, ret)) < 0)

        return ret;

    if (avpriv_dca_parse_core_frame_header(&gb, &h) < 0)

        return AVERROR_INVALIDDATA;

    *duration = h.npcmblocks * DCA_PCMBLOCK_SAMPLES;

    *sample_rate = avpriv_dca_sample_rates[h.sr_code];

    if (*profile != FF_PROFILE_UNKNOWN)

        return 0;

    *profile = FF_PROFILE_DTS;

    if (h.ext_audio_present) {

        switch (h.ext_audio_type) {

        case DCA_EXT_AUDIO_XCH:

        case DCA_EXT_AUDIO_XXCH:

            *profile = FF_PROFILE_DTS_ES;

            break;

        case DCA_EXT_AUDIO_X96:

            *profile = FF_PROFILE_DTS_96_24;

            break;

        }

    }

    frame_size = FFALIGN(h.frame_size, 4);

    if (buf_size - 4 < frame_size)

        return 0;

    buf      += frame_size;

    buf_size -= frame_size;

    if (AV_RB32(buf) != DCA_SYNCWORD_SUBSTREAM)

        return 0;

    if (ff_dca_exss_parse(&pc1->exss, buf, buf_size) < 0)

        return 0;

    if (asset->extension_mask & DCA_EXSS_XLL)

        *profile = FF_PROFILE_DTS_HD_MA;

    else if (asset->extension_mask & (DCA_EXSS_XBR | DCA_EXSS_XXCH | DCA_EXSS_X96))

        *profile = FF_PROFILE_DTS_HD_HRA;

    return 0;

}


static int ffmmal_fill_input_port(AVCodecContext *avctx)

{

    MMALDecodeContext *ctx = avctx->priv_data;

    while (ctx->waiting_buffers) {

        MMAL_BUFFER_HEADER_T *mbuffer;

        FFBufferEntry *buffer;

        MMAL_STATUS_T status;

        mbuffer = mmal_queue_get(ctx->pool_in->queue);

        if (!mbuffer)

            return 0;

        buffer = ctx->waiting_buffers;

        mmal_buffer_header_reset(mbuffer);

        mbuffer->cmd = 0;

        mbuffer->pts = buffer->pts;

        mbuffer->dts = buffer->dts;

        mbuffer->flags = buffer->flags;

        mbuffer->data = buffer->data;

        mbuffer->length = buffer->length;

        mbuffer->user_data = buffer->ref;

        mbuffer->alloc_size = ctx->decoder->input[0]->buffer_size;

        if ((status = mmal_port_send_buffer(ctx->decoder->input[0], mbuffer))) {

            mmal_buffer_header_release(mbuffer);

            av_buffer_unref(&buffer->ref);

        }

        // Remove from start of the list

        ctx->waiting_buffers = buffer->next;

        if (ctx->waiting_buffers_tail == buffer)

            ctx->waiting_buffers_tail = NULL;

        av_free(buffer);

        if (status) {

            av_log(avctx, AV_LOG_ERROR, "MMAL error %d when sending input\n", (int)status);

            return AVERROR_UNKNOWN;

        }

    }

    return 0;

}


static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,

                                        int jobnr, int threadnr, int is_vp7)

{

    VP8Context *s = avctx->priv_data;

    VP8ThreadData *prev_td, *next_td, *td = &s->thread_data[threadnr];

    int mb_y = td->thread_mb_pos >> 16;

    int mb_x, mb_xy = mb_y * s->mb_width;

    int num_jobs = s->num_jobs;

    VP8Frame *curframe = s->curframe, *prev_frame = s->prev_frame;

    VP56RangeCoder *c  = &s->coeff_partition[mb_y & (s->num_coeff_partitions - 1)];

    VP8Macroblock *mb;

    uint8_t *dst[3] = {

        curframe->tf.f->data[0] + 16 * mb_y * s->linesize,

        curframe->tf.f->data[1] +  8 * mb_y * s->uvlinesize,

        curframe->tf.f->data[2] +  8 * mb_y * s->uvlinesize

    };

    if (mb_y == 0)

        prev_td = td;

    else

        prev_td = &s->thread_data[(jobnr + num_jobs - 1) % num_jobs];

    if (mb_y == s->mb_height - 1)

        next_td = td;

    else

        next_td = &s->thread_data[(jobnr + 1) % num_jobs];

    if (s->mb_layout == 1)

        mb = s->macroblocks_base + ((s->mb_width + 1) * (mb_y + 1) + 1);

    else {

        // Make sure the previous frame has read its segmentation map,

        // if we re-use the same map.

        if (prev_frame && s->segmentation.enabled &&

            !s->segmentation.update_map)

            ff_thread_await_progress(&prev_frame->tf, mb_y, 0);

        mb = s->macroblocks + (s->mb_height - mb_y - 1) * 2;

        memset(mb - 1, 0, sizeof(*mb)); // zero left macroblock

        AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED * 0x01010101);

    }

    if (!is_vp7 || mb_y == 0)

        memset(td->left_nnz, 0, sizeof(td->left_nnz));

    s->mv_min.x = -MARGIN;

    s->mv_max.x = ((s->mb_width - 1) << 6) + MARGIN;

    for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {

        // Wait for previous thread to read mb_x+2, and reach mb_y-1.

        if (prev_td != td) {

            if (threadnr != 0) {

                check_thread_pos(td, prev_td,

                                 mb_x + (is_vp7 ? 2 : 1),

                                 mb_y - (is_vp7 ? 2 : 1));

            } else {

                check_thread_pos(td, prev_td,

                                 mb_x + (is_vp7 ? 2 : 1) + s->mb_width + 3,

                                 mb_y - (is_vp7 ? 2 : 1));

            }

        }

        s->vdsp.prefetch(dst[0] + (mb_x & 3) * 4 * s->linesize + 64,

                         s->linesize, 4);

        s->vdsp.prefetch(dst[1] + (mb_x & 7) * s->uvlinesize + 64,

                         dst[2] - dst[1], 2);

        if (!s->mb_layout)

            decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,

                           prev_frame && prev_frame->seg_map ?

                           prev_frame->seg_map->data + mb_xy : NULL, 0, is_vp7);

        prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_PREVIOUS);

        if (!mb->skip)

            decode_mb_coeffs(s, td, c, mb, s->top_nnz[mb_x], td->left_nnz, is_vp7);

        if (mb->mode <= MODE_I4x4)

            intra_predict(s, td, dst, mb, mb_x, mb_y, is_vp7);

        else

            inter_predict(s, td, dst, mb, mb_x, mb_y);

        prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_GOLDEN);

        if (!mb->skip) {

            idct_mb(s, td, dst, mb);

        } else {

            AV_ZERO64(td->left_nnz);

            AV_WN64(s->top_nnz[mb_x], 0);   // array of 9, so unaligned

            /* Reset DC block predictors if they would exist

             * if the mb had coefficients */

            if (mb->mode != MODE_I4x4 && mb->mode != VP8_MVMODE_SPLIT) {

                td->left_nnz[8]     = 0;

                s->top_nnz[mb_x][8] = 0;

            }

        }

        if (s->deblock_filter)

            filter_level_for_mb(s, mb, &td->filter_strength[mb_x], is_vp7);

        if (s->deblock_filter && num_jobs != 1 && threadnr == num_jobs - 1) {

            if (s->filter.simple)

                backup_mb_border(s->top_border[mb_x + 1], dst[0],

                                 NULL, NULL, s->linesize, 0, 1);

            else

                backup_mb_border(s->top_border[mb_x + 1], dst[0],

                                 dst[1], dst[2], s->linesize, s->uvlinesize, 0);

        }

        prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_GOLDEN2);

        dst[0]      += 16;

        dst[1]      += 8;

        dst[2]      += 8;

        s->mv_min.x -= 64;

        s->mv_max.x -= 64;

        if (mb_x == s->mb_width + 1) {

            update_pos(td, mb_y, s->mb_width + 3);

        } else {

            update_pos(td, mb_y, mb_x);

        }

    }

    return 0;

}


static test_speed(int step)

{

    const struct pix_func* pix = pix_func;

    const int linesize = 720;

    char empty[32768];

    char* bu =(char*)(((long)empty + 32) & ~0xf);

    int sum = 0;

    while (pix->name)

    {

	int i;

        uint64_t te, ts;

        op_pixels_func func = pix->func;

	char* im = bu;

	if (!(pix->mm_flags & mm_flags))

            continue;

	printf("%30s... ", pix->name);

        fflush(stdout);

	ts = rdtsc();

	for(i=0; i<100000; i++){

	    func(im, im + 1000, linesize, 16);

	    im += step;

	    if (im > bu + 20000)

		im = bu;

	}

	te = rdtsc();

        emms();

	printf("% 9d\n", (int)(te - ts));

        sum += (te - ts) / 100000;

	if (pix->mm_flags & PAD)

            puts("");

        pix++;

    }

    printf("Total sum: %d\n", sum);

}


static void writer_print_ts(WriterContext *wctx, const char *key, int64_t ts, int is_duration)

{

    if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) {

        writer_print_string(wctx, key, "N/A", 1);

    } else {

        writer_print_integer(wctx, key, ts);

    }

}


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);

        }

    }

}


void ff_avg_h264_qpel16_mc31_msa(uint8_t *dst, const uint8_t *src,

                                 ptrdiff_t stride)

{

    avc_luma_hv_qrt_and_aver_dst_16x16_msa(src - 2,

                                           src - (stride * 2) +

                                           sizeof(uint8_t), stride,

                                           dst, stride);

}


int av_tempfile(char *prefix, char **filename) {

    int fd=-1;

#ifdef __MINGW32__

    *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;

    }

#ifdef __MINGW32__

    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 */

}


static av_always_inline void xchg_mb_border(H264Context *h, H264SliceContext *sl,

                                            uint8_t *src_y,

                                            uint8_t *src_cb, uint8_t *src_cr,

                                            int linesize, int uvlinesize,

                                            int xchg, int chroma444,

                                            int simple, int pixel_shift)

{

    int deblock_topleft;

    int deblock_top;

    int top_idx = 1;

    uint8_t *top_border_m1;

    uint8_t *top_border;

    if (!simple && FRAME_MBAFF(h)) {

        if (h->mb_y & 1) {

            if (!MB_MBAFF(h))

                return;

        } else {

            top_idx = MB_MBAFF(h) ? 0 : 1;

        }

    }

    if (h->deblocking_filter == 2) {

        deblock_topleft = h->slice_table[h->mb_xy - 1 - h->mb_stride] == sl->slice_num;

        deblock_top     = sl->top_type;

    } else {

        deblock_topleft = (h->mb_x > 0);

        deblock_top     = (h->mb_y > !!MB_FIELD(h));

    }

    src_y  -= linesize   + 1 + pixel_shift;

    src_cb -= uvlinesize + 1 + pixel_shift;

    src_cr -= uvlinesize + 1 + pixel_shift;

    top_border_m1 = h->top_borders[top_idx][h->mb_x - 1];

    top_border    = h->top_borders[top_idx][h->mb_x];

#define XCHG(a, b, xchg)                        \

    if (pixel_shift) {                          \

        if (xchg) {                             \

            AV_SWAP64(b + 0, a + 0);            \

            AV_SWAP64(b + 8, a + 8);            \

        } else {                                \

            AV_COPY128(b, a);                   \

        }                                       \

    } else if (xchg)                            \

        AV_SWAP64(b, a);                        \

    else                                        \

        AV_COPY64(b, a);

    if (deblock_top) {

        if (deblock_topleft) {

            XCHG(top_border_m1 + (8 << pixel_shift),

                 src_y - (7 << pixel_shift), 1);

        }

        XCHG(top_border + (0 << pixel_shift), src_y + (1 << pixel_shift), xchg);

        XCHG(top_border + (8 << pixel_shift), src_y + (9 << pixel_shift), 1);

        if (h->mb_x + 1 < h->mb_width) {

            XCHG(h->top_borders[top_idx][h->mb_x + 1],

                 src_y + (17 << pixel_shift), 1);

        }

    }

    if (simple || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {

        if (chroma444) {

            if (deblock_top) {

                if (deblock_topleft) {

                    XCHG(top_border_m1 + (24 << pixel_shift), src_cb - (7 << pixel_shift), 1);

                    XCHG(top_border_m1 + (40 << pixel_shift), src_cr - (7 << pixel_shift), 1);

                }

                XCHG(top_border + (16 << pixel_shift), src_cb + (1 << pixel_shift), xchg);

                XCHG(top_border + (24 << pixel_shift), src_cb + (9 << pixel_shift), 1);

                XCHG(top_border + (32 << pixel_shift), src_cr + (1 << pixel_shift), xchg);

                XCHG(top_border + (40 << pixel_shift), src_cr + (9 << pixel_shift), 1);

                if (h->mb_x + 1 < h->mb_width) {

                    XCHG(h->top_borders[top_idx][h->mb_x + 1] + (16 << pixel_shift), src_cb + (17 << pixel_shift), 1);

                    XCHG(h->top_borders[top_idx][h->mb_x + 1] + (32 << pixel_shift), src_cr + (17 << pixel_shift), 1);

                }

            }

        } else {

            if (deblock_top) {

                if (deblock_topleft) {

                    XCHG(top_border_m1 + (16 << pixel_shift), src_cb - (7 << pixel_shift), 1);

                    XCHG(top_border_m1 + (24 << pixel_shift), src_cr - (7 << pixel_shift), 1);

                }

                XCHG(top_border + (16 << pixel_shift), src_cb + 1 + pixel_shift, 1);

                XCHG(top_border + (24 << pixel_shift), src_cr + 1 + pixel_shift, 1);

            }

        }

    }

}


unsigned int codec_get_tag(const CodecTag *tags, int id)

{

    while (tags->id != 0) {

        if (tags->id == id)

            return tags->tag;

        tags++;

    }

    return 0;

}


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 : AV_PICTURE_TYPE_I;
        if(MPV_frame_start(s, s->avctx) < 0)
            return -1;
        ff_er_frame_start(s);
        if (!r->tmp_b_block_base || s->width != r->si.width || s->height != r->si.height) {
            int i;
            av_free(r->tmp_b_block_base); //realloc() doesn't guarantee alignment
            r->tmp_b_block_base = av_malloc(s->linesize * 48);
            for (i = 0; i < 2; i++)
                r->tmp_b_block_y[i] = r->tmp_b_block_base + i * 16 * s->linesize;
            for (i = 0; i < 4; i++)
                r->tmp_b_block_uv[i] = r->tmp_b_block_base + 32 * s->linesize
                                       + (i >> 1) * 8 * s->uvlinesize + (i & 1) * 16;
        r->cur_pts = r->si.pts;
        if(s->pict_type != AV_PICTURE_TYPE_B){
            r->last_pts = r->next_pts;
            r->next_pts = r->cur_pts;
        }else{
            int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts);
            int dist0   = GET_PTS_DIFF(r->cur_pts,  r->last_pts);
            int dist1   = GET_PTS_DIFF(r->next_pts, r->cur_pts);
            if(!refdist){
                r->weight1 = r->weight2 = 8192;
            }else{
                r->weight1 = (dist0 << 14) / refdist;
                r->weight2 = (dist1 << 14) / refdist;
        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;


static inline void RENAME(bgr24ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)

{

#ifdef HAVE_MMX

	asm volatile(

		"mov %4, %%"REG_a"		\n\t"

		"movq "MANGLE(w1111)", %%mm5		\n\t"

		"movq "MANGLE(bgr2UCoeff)", %%mm6		\n\t"

		"pxor %%mm7, %%mm7		\n\t"

		"lea (%%"REG_a", %%"REG_a", 2), %%"REG_b"	\n\t"

		"add %%"REG_b", %%"REG_b"	\n\t"

		".balign 16			\n\t"

		"1:				\n\t"

		PREFETCH" 64(%0, %%"REG_b")	\n\t"

		PREFETCH" 64(%1, %%"REG_b")	\n\t"

#if defined (HAVE_MMX2) || defined (HAVE_3DNOW)

		"movq (%0, %%"REG_b"), %%mm0	\n\t"

		"movq (%1, %%"REG_b"), %%mm1	\n\t"

		"movq 6(%0, %%"REG_b"), %%mm2	\n\t"

		"movq 6(%1, %%"REG_b"), %%mm3	\n\t"

		PAVGB(%%mm1, %%mm0)

		PAVGB(%%mm3, %%mm2)

		"movq %%mm0, %%mm1		\n\t"

		"movq %%mm2, %%mm3		\n\t"

		"psrlq $24, %%mm0		\n\t"

		"psrlq $24, %%mm2		\n\t"

		PAVGB(%%mm1, %%mm0)

		PAVGB(%%mm3, %%mm2)

		"punpcklbw %%mm7, %%mm0		\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

#else

		"movd (%0, %%"REG_b"), %%mm0	\n\t"

		"movd (%1, %%"REG_b"), %%mm1	\n\t"

		"movd 3(%0, %%"REG_b"), %%mm2	\n\t"

		"movd 3(%1, %%"REG_b"), %%mm3	\n\t"

		"punpcklbw %%mm7, %%mm0		\n\t"

		"punpcklbw %%mm7, %%mm1		\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

		"punpcklbw %%mm7, %%mm3		\n\t"

		"paddw %%mm1, %%mm0		\n\t"

		"paddw %%mm3, %%mm2		\n\t"

		"paddw %%mm2, %%mm0		\n\t"

		"movd 6(%0, %%"REG_b"), %%mm4	\n\t"

		"movd 6(%1, %%"REG_b"), %%mm1	\n\t"

		"movd 9(%0, %%"REG_b"), %%mm2	\n\t"

		"movd 9(%1, %%"REG_b"), %%mm3	\n\t"

		"punpcklbw %%mm7, %%mm4		\n\t"

		"punpcklbw %%mm7, %%mm1		\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

		"punpcklbw %%mm7, %%mm3		\n\t"

		"paddw %%mm1, %%mm4		\n\t"

		"paddw %%mm3, %%mm2		\n\t"

		"paddw %%mm4, %%mm2		\n\t"

		"psrlw $2, %%mm0		\n\t"

		"psrlw $2, %%mm2		\n\t"

#endif

		"movq "MANGLE(bgr2VCoeff)", %%mm1		\n\t"

		"movq "MANGLE(bgr2VCoeff)", %%mm3		\n\t"

		"pmaddwd %%mm0, %%mm1		\n\t"

		"pmaddwd %%mm2, %%mm3		\n\t"

		"pmaddwd %%mm6, %%mm0		\n\t"

		"pmaddwd %%mm6, %%mm2		\n\t"

#ifndef FAST_BGR2YV12

		"psrad $8, %%mm0		\n\t"

		"psrad $8, %%mm1		\n\t"

		"psrad $8, %%mm2		\n\t"

		"psrad $8, %%mm3		\n\t"

#endif

		"packssdw %%mm2, %%mm0		\n\t"

		"packssdw %%mm3, %%mm1		\n\t"

		"pmaddwd %%mm5, %%mm0		\n\t"

		"pmaddwd %%mm5, %%mm1		\n\t"

		"packssdw %%mm1, %%mm0		\n\t" // V1 V0 U1 U0

		"psraw $7, %%mm0		\n\t"

#if defined (HAVE_MMX2) || defined (HAVE_3DNOW)

		"movq 12(%0, %%"REG_b"), %%mm4	\n\t"

		"movq 12(%1, %%"REG_b"), %%mm1	\n\t"

		"movq 18(%0, %%"REG_b"), %%mm2	\n\t"

		"movq 18(%1, %%"REG_b"), %%mm3	\n\t"

		PAVGB(%%mm1, %%mm4)

		PAVGB(%%mm3, %%mm2)

		"movq %%mm4, %%mm1		\n\t"

		"movq %%mm2, %%mm3		\n\t"

		"psrlq $24, %%mm4		\n\t"

		"psrlq $24, %%mm2		\n\t"

		PAVGB(%%mm1, %%mm4)

		PAVGB(%%mm3, %%mm2)

		"punpcklbw %%mm7, %%mm4		\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

#else

		"movd 12(%0, %%"REG_b"), %%mm4	\n\t"

		"movd 12(%1, %%"REG_b"), %%mm1	\n\t"

		"movd 15(%0, %%"REG_b"), %%mm2	\n\t"

		"movd 15(%1, %%"REG_b"), %%mm3	\n\t"

		"punpcklbw %%mm7, %%mm4		\n\t"

		"punpcklbw %%mm7, %%mm1		\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

		"punpcklbw %%mm7, %%mm3		\n\t"

		"paddw %%mm1, %%mm4		\n\t"

		"paddw %%mm3, %%mm2		\n\t"

		"paddw %%mm2, %%mm4		\n\t"

		"movd 18(%0, %%"REG_b"), %%mm5	\n\t"

		"movd 18(%1, %%"REG_b"), %%mm1	\n\t"

		"movd 21(%0, %%"REG_b"), %%mm2	\n\t"

		"movd 21(%1, %%"REG_b"), %%mm3	\n\t"

		"punpcklbw %%mm7, %%mm5		\n\t"

		"punpcklbw %%mm7, %%mm1		\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

		"punpcklbw %%mm7, %%mm3		\n\t"

		"paddw %%mm1, %%mm5		\n\t"

		"paddw %%mm3, %%mm2		\n\t"

		"paddw %%mm5, %%mm2		\n\t"

		"movq "MANGLE(w1111)", %%mm5		\n\t"

		"psrlw $2, %%mm4		\n\t"

		"psrlw $2, %%mm2		\n\t"

#endif

		"movq "MANGLE(bgr2VCoeff)", %%mm1		\n\t"

		"movq "MANGLE(bgr2VCoeff)", %%mm3		\n\t"

		"pmaddwd %%mm4, %%mm1		\n\t"

		"pmaddwd %%mm2, %%mm3		\n\t"

		"pmaddwd %%mm6, %%mm4		\n\t"

		"pmaddwd %%mm6, %%mm2		\n\t"

#ifndef FAST_BGR2YV12

		"psrad $8, %%mm4		\n\t"

		"psrad $8, %%mm1		\n\t"

		"psrad $8, %%mm2		\n\t"

		"psrad $8, %%mm3		\n\t"

#endif

		"packssdw %%mm2, %%mm4		\n\t"

		"packssdw %%mm3, %%mm1		\n\t"

		"pmaddwd %%mm5, %%mm4		\n\t"

		"pmaddwd %%mm5, %%mm1		\n\t"

		"add $24, %%"REG_b"		\n\t"

		"packssdw %%mm1, %%mm4		\n\t" // V3 V2 U3 U2

		"psraw $7, %%mm4		\n\t"

		"movq %%mm0, %%mm1		\n\t"

		"punpckldq %%mm4, %%mm0		\n\t"

		"punpckhdq %%mm4, %%mm1		\n\t"

		"packsswb %%mm1, %%mm0		\n\t"

		"paddb "MANGLE(bgr2UVOffset)", %%mm0	\n\t"

		"movd %%mm0, (%2, %%"REG_a")	\n\t"

		"punpckhdq %%mm0, %%mm0		\n\t"

		"movd %%mm0, (%3, %%"REG_a")	\n\t"

		"add $4, %%"REG_a"		\n\t"

		" js 1b				\n\t"

		: : "r" (src1+width*6), "r" (src2+width*6), "r" (dstU+width), "r" (dstV+width), "g" ((long)-width)

		: "%"REG_a, "%"REG_b

	);

#else

	int i;

	for(i=0; i<width; i++)

	{

		int b= src1[6*i + 0] + src1[6*i + 3] + src2[6*i + 0] + src2[6*i + 3];

		int g= src1[6*i + 1] + src1[6*i + 4] + src2[6*i + 1] + src2[6*i + 4];

		int r= src1[6*i + 2] + src1[6*i + 5] + src2[6*i + 2] + src2[6*i + 5];

		dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+2)) + 128;

		dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+2)) + 128;

	}

#endif

}


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 inline uint32_t celt_icwrsi(uint32_t N, uint32_t K, const int *y)

{

    int i, idx = 0, sum = 0;

    for (i = N - 1; i >= 0; i--) {

        const uint32_t i_s = CELT_PVQ_U(N - i, sum + FFABS(y[i]) + 1);

        idx += CELT_PVQ_U(N - i, sum) + (y[i] < 0)*i_s;

        sum += FFABS(y[i]);

    }

    av_assert0(sum == K);

    return idx;

}


static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)

{

    MatroskaDemuxContext *matroska = s->priv_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;

    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) || strcmp(ebml.doctype, "matroska")

        || 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);

        return AVERROR_NOFMT;

    }

    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;

    if (matroska->title)

        strncpy(matroska->ctx->title, matroska->title,

                sizeof(matroska->ctx->title)-1);

    matroska_convert_tags(s, &matroska->tags);

    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;

        /* 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 &&

#ifdef CONFIG_ZLIB

                 encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_ZLIB &&

#endif

#ifdef 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->video.fourcc = AV_RL32(track->codec_priv.data + 16);

            codec_id = codec_get_id(codec_bmp_tags, track->video.fourcc);

        } else if (!strcmp(track->codec_id, "A_MS/ACM")

                   && track->codec_priv.size >= 18

                   && track->codec_priv.data != NULL) {

            uint16_t tag = AV_RL16(track->codec_priv.data);

            codec_id = codec_get_id(codec_wav_tags, tag);

        } 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=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) {

            ByteIOContext b;

            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;

            track->codec_priv.size -= extradata_offset;

        } 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) {

            ByteIOContext b;

            init_put_byte(&b, track->codec_priv.data,track->codec_priv.size,

                          0, NULL, NULL, NULL, NULL);

            url_fskip(&b, 24);

            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 {

                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_strlcpy(st->language, track->language, 4);

        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(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_malloc(track->codec_priv.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 = CODEC_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);

            st->need_parsing = AVSTREAM_PARSE_HEADERS;

        } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {

            st->codec->codec_type = CODEC_TYPE_AUDIO;

            st->codec->sample_rate = track->audio.out_samplerate;

            st->codec->channels = track->audio.channels;

        } else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) {

            st->codec->codec_type = CODEC_TYPE_SUBTITLE;

        }

    }

    attachements = attachements_list->elem;

    for (j=0; j<attachements_list->nb_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;

            st->filename          = av_strdup(attachements[j].filename);

            st->codec->codec_id = CODEC_ID_NONE;

            st->codec->codec_type = CODEC_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;

                }

            }

        }

    }

    chapters = chapters_list->elem;

    for (i=0; i<chapters_list->nb_elem; i++)

        if (chapters[i].start != AV_NOPTS_VALUE && chapters[i].uid)

            ff_new_chapter(s, chapters[i].uid, (AVRational){1, 1000000000},

                           chapters[i].start, chapters[i].end,

                           chapters[i].title);

    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; i<index_list->nb_elem; i++) {

        EbmlList *pos_list = &index[i].pos;

        MatroskaIndexPos *pos = pos_list->elem;

        for (j=0; j<pos_list->nb_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);

        }

    }

    return 0;

}


static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
{
    VP56RangeCoder *c = &s->c;
    int header_size, hscale, vscale, ret;
    int width  = s->avctx->width;
    int height = s->avctx->height;
    s->keyframe  = !(buf[0] & 1);
    s->profile   =  (buf[0]>>1) & 7;
    s->invisible = !(buf[0] & 0x10);
    header_size  = AV_RL24(buf) >> 5;
    buf      += 3;
    buf_size -= 3;
    if (s->profile > 3)
        av_log(s->avctx, AV_LOG_WARNING, "Unknown profile %d\n", s->profile);
    if (!s->profile)
        memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab,
               sizeof(s->put_pixels_tab));
    else    // profile 1-3 use bilinear, 4+ aren't defined so whatever
        memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_bilinear_pixels_tab,
               sizeof(s->put_pixels_tab));
    if (header_size > buf_size - 7 * s->keyframe) {
        av_log(s->avctx, AV_LOG_ERROR, "Header size larger than data provided\n");
    if (s->keyframe) {
        if (AV_RL24(buf) != 0x2a019d) {
            av_log(s->avctx, AV_LOG_ERROR,
                   "Invalid start code 0x%x\n", AV_RL24(buf));
        width     = AV_RL16(buf + 3) & 0x3fff;
        height    = AV_RL16(buf + 5) & 0x3fff;
        hscale    = buf[4] >> 6;
        vscale    = buf[6] >> 6;
        buf      += 7;
        buf_size -= 7;
        if (hscale || vscale)
            avpriv_request_sample(s->avctx, "Upscaling");
        s->update_golden = s->update_altref = VP56_FRAME_CURRENT;
        vp78_reset_probability_tables(s);
        memcpy(s->prob->pred16x16, vp8_pred16x16_prob_inter,
               sizeof(s->prob->pred16x16));
        memcpy(s->prob->pred8x8c, vp8_pred8x8c_prob_inter,
               sizeof(s->prob->pred8x8c));
        memcpy(s->prob->mvc, vp8_mv_default_prob,
               sizeof(s->prob->mvc));
        memset(&s->segmentation, 0, sizeof(s->segmentation));
        memset(&s->lf_delta, 0, sizeof(s->lf_delta));
    ff_vp56_init_range_decoder(c, buf, header_size);
    buf      += header_size;
    buf_size -= header_size;
    if (s->keyframe) {
        s->colorspace = vp8_rac_get(c);
        if (s->colorspace)
            av_log(s->avctx, AV_LOG_WARNING, "Unspecified colorspace\n");
        s->fullrange = vp8_rac_get(c);
    if ((s->segmentation.enabled = vp8_rac_get(c)))
        parse_segment_info(s);
    else
        s->segmentation.update_map = 0; // FIXME: move this to some init function?
    s->filter.simple    = vp8_rac_get(c);
    s->filter.level     = vp8_rac_get_uint(c, 6);
    s->filter.sharpness = vp8_rac_get_uint(c, 3);
    if ((s->lf_delta.enabled = vp8_rac_get(c)))
        if (vp8_rac_get(c))
            update_lf_deltas(s);
    if (setup_partitions(s, buf, buf_size)) {
        av_log(s->avctx, AV_LOG_ERROR, "Invalid partitions\n");
    if (!s->macroblocks_base || /* first frame */
        width != s->avctx->width || height != s->avctx->height ||
        (width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height)
        if ((ret = vp8_update_dimensions(s, width, height)) < 0)
            return ret;
    vp8_get_quants(s);
    if (!s->keyframe) {
        update_refs(s);
        s->sign_bias[VP56_FRAME_GOLDEN]               = vp8_rac_get(c);
        s->sign_bias[VP56_FRAME_GOLDEN2 /* altref */] = vp8_rac_get(c);
    // if we aren't saving this frame's probabilities for future frames,
    // make a copy of the current probabilities
    if (!(s->update_probabilities = vp8_rac_get(c)))
        s->prob[1] = s->prob[0];
    s->update_last = s->keyframe || vp8_rac_get(c);
    vp78_update_probability_tables(s);
    if ((s->mbskip_enabled = vp8_rac_get(c)))
        s->prob->mbskip = vp8_rac_get_uint(c, 8);
    if (!s->keyframe) {
        s->prob->intra  = vp8_rac_get_uint(c, 8);
        s->prob->last   = vp8_rac_get_uint(c, 8);
        s->prob->golden = vp8_rac_get_uint(c, 8);
        vp78_update_pred16x16_pred8x8_mvc_probabilities(s, VP8_MVC_SIZE);
    return 0;


static float voice_factor(float *p_vector, float p_gain,

                          float *f_vector, float f_gain,

                          CELPMContext *ctx)

{

    double p_ener = (double) ctx->dot_productf(p_vector, p_vector,

                                                          AMRWB_SFR_SIZE) *

                    p_gain * p_gain;

    double f_ener = (double) ctx->dot_productf(f_vector, f_vector,

                                                          AMRWB_SFR_SIZE) *

                    f_gain * f_gain;

    return (p_ener - f_ener) / (p_ener + f_ener);

}


static int qcrypto_cipher_setiv_aes(QCryptoCipher *cipher,

                                     const uint8_t *iv, size_t niv,

                                     Error **errp)

{

    QCryptoCipherBuiltin *ctxt = cipher->opaque;

    if (niv != 16) {

        error_setg(errp, "IV must be 16 bytes not %zu", niv);

        return -1;

    }

    g_free(ctxt->state.aes.iv);

    ctxt->state.aes.iv = g_new0(uint8_t, niv);

    memcpy(ctxt->state.aes.iv, iv, niv);

    ctxt->state.aes.niv = niv;

    return 0;

}


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, ret = 0;

    zero = av_mallocz(s->picture_ptr->linesize[0]);

    if (!zero)

        return AVERROR(ENOMEM);

    last = zero;

    cur  = s->picture_ptr->data[0];

    state = av_mallocz(sizeof(JLSState));

    if (!state) {

        av_free(zero);

        return AVERROR(ENOMEM);

    }

    /* 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);

    if (shift >= 16) {

        ret = AVERROR_INVALIDDATA;

    }

    if (s->avctx->debug & FF_DEBUG_PICT_INFO) {

        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 (get_bits_left(&s->gb) < s->height) {

        ret = AVERROR_INVALIDDATA;

    }

    if (ilv == 0) { /* separate planes */

        if (s->cur_scan > s->nb_components) {

            ret = AVERROR_INVALIDDATA;

        }

        stride = (s->nb_components > 1) ? 3 : 1;

        off    = av_clip(s->cur_scan - 1, 0, stride - 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_ptr->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 };

        stride = (s->nb_components > 1) ? 3 : 1;

        memset(cur, 0, s->picture_ptr->linesize[0]);

        width = s->width * stride;

        for (i = 0; i < s->height; i++) {

            for (j = 0; j < stride; j++) {

                ls_decode_line(state, s, last + j, cur + j,

                               Rc[j], width, stride, 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_ptr->linesize[0];

        }

    } else if (ilv == 2) { /* sample interleaving */

        avpriv_report_missing_feature(s->avctx, "Sample interleaved images");

    }

    if (s->xfrm && s->nb_components == 3) {

        int x, w;

        w = s->width * s->nb_components;

        if (s->bits <= 8) {

            uint8_t *src = s->picture_ptr->data[0];

            for (i = 0; i < s->height; i++) {

                switch(s->xfrm) {

                case 1:

                    for (x = off; x < w; x += 3) {

                        src[x  ] += src[x+1] + 128;

                        src[x+2] += src[x+1] + 128;

                    }

                    break;

                case 2:

                    for (x = off; x < w; x += 3) {

                        src[x  ] += src[x+1] + 128;

                        src[x+2] += ((src[x  ] + src[x+1])>>1) + 128;

                    }

                    break;

                case 3:

                    for (x = off; x < w; x += 3) {

                        int g = src[x+0] - ((src[x+2]+src[x+1])>>2) + 64;

                        src[x+0] = src[x+2] + g + 128;

                        src[x+2] = src[x+1] + g + 128;

                        src[x+1] = g;

                    }

                    break;

                case 4:

                    for (x = off; x < w; x += 3) {

                        int r    = src[x+0] - ((                       359 * (src[x+2]-128) + 490) >> 8);

                        int g    = src[x+0] - (( 88 * (src[x+1]-128) - 183 * (src[x+2]-128) +  30) >> 8);

                        int b    = src[x+0] + ((454 * (src[x+1]-128)                        + 574) >> 8);

                        src[x+0] = av_clip_uint8(r);

                        src[x+1] = av_clip_uint8(g);

                        src[x+2] = av_clip_uint8(b);

                    }

                    break;

                }

                src += s->picture_ptr->linesize[0];

            }

        }else

            avpriv_report_missing_feature(s->avctx, "16bit xfrm");

    }

    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_ptr->data[0];

            for (i = 0; i < s->height; i++) {

                for (x = off; x < w; x += stride)

                    src[x] <<= shift;

                src += s->picture_ptr->linesize[0];

            }

        } else {

            uint16_t *src = (uint16_t *)s->picture_ptr->data[0];

            for (i = 0; i < s->height; i++) {

                for (x = 0; x < w; x++)

                    src[x] <<= shift;

                src += s->picture_ptr->linesize[0] / 2;

            }

        }

    }

end:

    av_free(state);

    av_free(zero);

    return ret;

}


static void create_gic(const VirtBoardInfo *vbi, qemu_irq *pic)

{

    /* We create a standalone GIC v2 */

    DeviceState *gicdev;

    SysBusDevice *gicbusdev;

    const char *gictype = "arm_gic";

    int i;

    if (kvm_irqchip_in_kernel()) {

        gictype = "kvm-arm-gic";

    }

    gicdev = qdev_create(NULL, gictype);

    qdev_prop_set_uint32(gicdev, "revision", 2);

    qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);

    /* Note that the num-irq property counts both internal and external

     * interrupts; there are always 32 of the former (mandated by GIC spec).

     */

    qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);

    qdev_init_nofail(gicdev);

    gicbusdev = SYS_BUS_DEVICE(gicdev);

    sysbus_mmio_map(gicbusdev, 0, vbi->memmap[VIRT_GIC_DIST].base);

    sysbus_mmio_map(gicbusdev, 1, vbi->memmap[VIRT_GIC_CPU].base);

    /* Wire the outputs from each CPU's generic timer to the

     * appropriate GIC PPI inputs, and the GIC's IRQ output to

     * the CPU's IRQ input.

     */

    for (i = 0; i < smp_cpus; i++) {

        DeviceState *cpudev = DEVICE(qemu_get_cpu(i));

        int ppibase = NUM_IRQS + i * 32;

        /* physical timer; we wire it up to the non-secure timer's ID,

         * since a real A15 always has TrustZone but QEMU doesn't.

         */

        qdev_connect_gpio_out(cpudev, 0,

                              qdev_get_gpio_in(gicdev, ppibase + 30));

        /* virtual timer */

        qdev_connect_gpio_out(cpudev, 1,

                              qdev_get_gpio_in(gicdev, ppibase + 27));

        sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));

    }

    for (i = 0; i < NUM_IRQS; i++) {

        pic[i] = qdev_get_gpio_in(gicdev, i);

    }

    fdt_add_gic_node(vbi);

}


virtio_crypto_sym_op_helper(VirtIODevice *vdev,

           struct virtio_crypto_cipher_para *cipher_para,

           struct virtio_crypto_alg_chain_data_para *alg_chain_para,

           struct iovec *iov, unsigned int out_num)

{

    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);

    CryptoDevBackendSymOpInfo *op_info;

    uint32_t src_len = 0, dst_len = 0;

    uint32_t iv_len = 0;

    uint32_t aad_len = 0, hash_result_len = 0;

    uint32_t hash_start_src_offset = 0, len_to_hash = 0;

    uint32_t cipher_start_src_offset = 0, len_to_cipher = 0;

    size_t max_len, curr_size = 0;

    size_t s;

    /* Plain cipher */

    if (cipher_para) {

        iv_len = ldl_le_p(&cipher_para->iv_len);

        src_len = ldl_le_p(&cipher_para->src_data_len);

        dst_len = ldl_le_p(&cipher_para->dst_data_len);

    } else if (alg_chain_para) { /* Algorithm chain */

        iv_len = ldl_le_p(&alg_chain_para->iv_len);

        src_len = ldl_le_p(&alg_chain_para->src_data_len);

        dst_len = ldl_le_p(&alg_chain_para->dst_data_len);

        aad_len = ldl_le_p(&alg_chain_para->aad_len);

        hash_result_len = ldl_le_p(&alg_chain_para->hash_result_len);

        hash_start_src_offset = ldl_le_p(

                         &alg_chain_para->hash_start_src_offset);

        cipher_start_src_offset = ldl_le_p(

                         &alg_chain_para->cipher_start_src_offset);

        len_to_cipher = ldl_le_p(&alg_chain_para->len_to_cipher);

        len_to_hash = ldl_le_p(&alg_chain_para->len_to_hash);

    } else {

        return NULL;

    }

    max_len = iv_len + aad_len + src_len + dst_len + hash_result_len;

    if (unlikely(max_len > vcrypto->conf.max_size)) {

        virtio_error(vdev, "virtio-crypto too big length");

        return NULL;

    }

    op_info = g_malloc0(sizeof(CryptoDevBackendSymOpInfo) + max_len);

    op_info->iv_len = iv_len;

    op_info->src_len = src_len;

    op_info->dst_len = dst_len;

    op_info->aad_len = aad_len;

    op_info->digest_result_len = hash_result_len;

    op_info->hash_start_src_offset = hash_start_src_offset;

    op_info->len_to_hash = len_to_hash;

    op_info->cipher_start_src_offset = cipher_start_src_offset;

    op_info->len_to_cipher = len_to_cipher;

    /* Handle the initilization vector */

    if (op_info->iv_len > 0) {

        DPRINTF("iv_len=%" PRIu32 "\n", op_info->iv_len);

        op_info->iv = op_info->data + curr_size;

        s = iov_to_buf(iov, out_num, 0, op_info->iv, op_info->iv_len);

        if (unlikely(s != op_info->iv_len)) {

            virtio_error(vdev, "virtio-crypto iv incorrect");

            goto err;

        }

        iov_discard_front(&iov, &out_num, op_info->iv_len);

        curr_size += op_info->iv_len;

    }

    /* Handle additional authentication data if exists */

    if (op_info->aad_len > 0) {

        DPRINTF("aad_len=%" PRIu32 "\n", op_info->aad_len);

        op_info->aad_data = op_info->data + curr_size;

        s = iov_to_buf(iov, out_num, 0, op_info->aad_data, op_info->aad_len);

        if (unlikely(s != op_info->aad_len)) {

            virtio_error(vdev, "virtio-crypto additional auth data incorrect");

            goto err;

        }

        iov_discard_front(&iov, &out_num, op_info->aad_len);

        curr_size += op_info->aad_len;

    }

    /* Handle the source data */

    if (op_info->src_len > 0) {

        DPRINTF("src_len=%" PRIu32 "\n", op_info->src_len);

        op_info->src = op_info->data + curr_size;

        s = iov_to_buf(iov, out_num, 0, op_info->src, op_info->src_len);

        if (unlikely(s != op_info->src_len)) {

            virtio_error(vdev, "virtio-crypto source data incorrect");

            goto err;

        }

        iov_discard_front(&iov, &out_num, op_info->src_len);

        curr_size += op_info->src_len;

    }

    /* Handle the destination data */

    op_info->dst = op_info->data + curr_size;

    curr_size += op_info->dst_len;

    DPRINTF("dst_len=%" PRIu32 "\n", op_info->dst_len);

    /* Handle the hash digest result */

    if (hash_result_len > 0) {

        DPRINTF("hash_result_len=%" PRIu32 "\n", hash_result_len);

        op_info->digest_result = op_info->data + curr_size;

    }

    return op_info;

err:

    g_free(op_info);

    return NULL;

}


int net_slirp_parse_legacy(QemuOptsList *opts_list, const char *optarg, int *ret)

{

    if (strcmp(opts_list->name, "net") != 0 ||

        strncmp(optarg, "channel,", strlen("channel,")) != 0) {

        return 0;

    }

    error_report("The '-net channel' option is deprecated. "

                 "Please use '-netdev user,guestfwd=...' instead.");

    /* handle legacy -net channel,port:chr */

    optarg += strlen("channel,");

    if (QTAILQ_EMPTY(&slirp_stacks)) {

        struct slirp_config_str *config;

        config = g_malloc(sizeof(*config));

        pstrcpy(config->str, sizeof(config->str), optarg);

        config->flags = SLIRP_CFG_LEGACY;

        config->next = slirp_configs;

        slirp_configs = config;

        *ret = 0;

    } else {

        *ret = slirp_guestfwd(QTAILQ_FIRST(&slirp_stacks), optarg, 1);

    }

    return 1;

}


static int shall_we_drop(AVFormatContext *s)

{

    struct dshow_ctx *ctx = s->priv_data;

    static 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->video_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 int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)

{

    int acc, rd0, rd1, rdhi, rdlo;

    TCGv tmp, tmp2;

    if ((insn & 0x0ff00f10) == 0x0e200010) {

        /* Multiply with Internal Accumulate Format */

        rd0 = (insn >> 12) & 0xf;

        rd1 = insn & 0xf;

        acc = (insn >> 5) & 7;

        if (acc != 0)

            return 1;

        tmp = load_reg(s, rd0);

        tmp2 = load_reg(s, rd1);

        switch ((insn >> 16) & 0xf) {

        case 0x0:					/* MIA */

            gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);

            break;

        case 0x8:					/* MIAPH */

            gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);

            break;

        case 0xc:					/* MIABB */

        case 0xd:					/* MIABT */

        case 0xe:					/* MIATB */

        case 0xf:					/* MIATT */

            if (insn & (1 << 16))

                tcg_gen_shri_i32(tmp, tmp, 16);

            if (insn & (1 << 17))

                tcg_gen_shri_i32(tmp2, tmp2, 16);

            gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);

            break;

        default:

            return 1;

        }

        dead_tmp(tmp2);

        dead_tmp(tmp);

        gen_op_iwmmxt_movq_wRn_M0(acc);

        return 0;

    }

    if ((insn & 0x0fe00ff8) == 0x0c400000) {

        /* Internal Accumulator Access Format */

        rdhi = (insn >> 16) & 0xf;

        rdlo = (insn >> 12) & 0xf;

        acc = insn & 7;

        if (acc != 0)

            return 1;

        if (insn & ARM_CP_RW_BIT) {			/* MRA */

            iwmmxt_load_reg(cpu_V0, acc);

            tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);

            tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);

            tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);

            tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);

        } else {					/* MAR */

            tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);

            iwmmxt_store_reg(cpu_V0, acc);

        }

        return 0;

    }

    return 1;

}


static void decode_profile_tier_level(HEVCContext *s, PTLCommon *ptl)

{

    int i;

    HEVCLocalContext *lc = s->HEVClc;

    GetBitContext *gb = &lc->gb;

    ptl->profile_space = get_bits(gb, 2);

    ptl->tier_flag     = get_bits1(gb);

    ptl->profile_idc   = get_bits(gb, 5);

    if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN)

        av_log(s->avctx, AV_LOG_DEBUG, "Main profile bitstream\n");

    else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_10)

        av_log(s->avctx, AV_LOG_DEBUG, "Main 10 profile bitstream\n");

    else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_STILL_PICTURE)

        av_log(s->avctx, AV_LOG_DEBUG, "Main Still Picture profile bitstream\n");

    else if (ptl->profile_idc == FF_PROFILE_HEVC_REXT)

        av_log(s->avctx, AV_LOG_DEBUG, "Range Extension profile bitstream\n");

    else

        av_log(s->avctx, AV_LOG_WARNING, "Unknown HEVC profile: %d\n", ptl->profile_idc);

    for (i = 0; i < 32; i++)

        ptl->profile_compatibility_flag[i] = get_bits1(gb);

    ptl->progressive_source_flag    = get_bits1(gb);

    ptl->interlaced_source_flag     = get_bits1(gb);

    ptl->non_packed_constraint_flag = get_bits1(gb);

    ptl->frame_only_constraint_flag = get_bits1(gb);

    skip_bits(gb, 16); // XXX_reserved_zero_44bits[0..15]

    skip_bits(gb, 16); // XXX_reserved_zero_44bits[16..31]

    skip_bits(gb, 12); // XXX_reserved_zero_44bits[32..43]

}


qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,

                        qemu_irq **irqs, qemu_irq irq_out)

{

    openpic_t *mpp;

    int i;

    struct {

        CPUReadMemoryFunc * const *read;

        CPUWriteMemoryFunc * const *write;

        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},

    };

    /* XXX: for now, only one CPU is supported */

    if (nb_cpus != 1)

        return NULL;

    mpp = g_malloc0(sizeof(openpic_t));

    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);

    }

    mpp->nb_cpus = nb_cpus;

    mpp->max_irq = MPIC_MAX_IRQ;

    mpp->irq_ipi0 = MPIC_IPI_IRQ;

    mpp->irq_tim0 = MPIC_TMR_IRQ;

    for (i = 0; i < nb_cpus; i++)

        mpp->dst[i].irqs = irqs[i];

    mpp->irq_out = irq_out;

    mpp->irq_raise = mpic_irq_raise;

    mpp->reset = mpic_reset;

    register_savevm(NULL, "mpic", 0, 2, openpic_save, openpic_load, mpp);

    qemu_register_reset(mpic_reset, mpp);

    return qemu_allocate_irqs(openpic_set_irq, mpp, mpp->max_irq);

free:

    g_free(mpp);

    return NULL;

}


static void float_to_int16_stride_altivec(int16_t *dst, const float *src,

                                          long len, int stride)

{

    int i, j;

    vector signed short d, s;

    for (i = 0; i < len - 7; i += 8) {

        d = float_to_int16_one_altivec(src + i);

        for (j = 0; j < 8; j++) {

            s = vec_splat(d, j);

            vec_ste(s, 0, dst);

            dst += stride;

        }

    }

}


ssize_t iov_send_recv(int sockfd, struct iovec *iov,

                      size_t offset, size_t bytes,

                      bool do_sendv)

{

    int iovlen;

    ssize_t ret;

    size_t diff;

    struct iovec *last_iov;

    /* last_iov is inclusive, so count from one.  */

    iovlen = 1;

    last_iov = iov;

    bytes += offset;

    while (last_iov->iov_len < bytes) {

        bytes -= last_iov->iov_len;

        last_iov++;

        iovlen++;

    }

    diff = last_iov->iov_len - bytes;

    last_iov->iov_len -= diff;

    while (iov->iov_len <= offset) {

        offset -= iov->iov_len;

        iov++;

        iovlen--;

    }

    iov->iov_base = (char *) iov->iov_base + offset;

    iov->iov_len -= offset;

    {

#if defined CONFIG_IOVEC && defined CONFIG_POSIX

        struct msghdr msg;

        memset(&msg, 0, sizeof(msg));

        msg.msg_iov = iov;

        msg.msg_iovlen = iovlen;

        do {

            if (do_sendv) {

                ret = sendmsg(sockfd, &msg, 0);

            } else {

                ret = recvmsg(sockfd, &msg, 0);

            }

        } while (ret == -1 && errno == EINTR);

#else

        struct iovec *p = iov;

        ret = 0;

        while (iovlen > 0) {

            int rc;

            if (do_sendv) {

                rc = send(sockfd, p->iov_base, p->iov_len, 0);

            } else {

                rc = qemu_recv(sockfd, p->iov_base, p->iov_len, 0);

            }

            if (rc == -1) {

                if (errno == EINTR) {

                    continue;

                }

                if (ret == 0) {

                    ret = -1;

                }

                break;

            }

            if (rc == 0) {

                break;

            }

            ret += rc;

            iovlen--, p++;

        }

#endif

    }

    /* Undo the changes above */

    iov->iov_base = (char *) iov->iov_base - offset;

    iov->iov_len += offset;

    last_iov->iov_len += diff;

    return ret;

}


static long do_rt_sigreturn_v2(CPUARMState *env)

{

    abi_ulong frame_addr;

    struct rt_sigframe_v2 *frame = NULL;

    /*

     * Since we stacked the signal on a 64-bit boundary,

     * then 'sp' should be word aligned here.  If it's

     * not, then the user is trying to mess with us.

     */

    frame_addr = env->regs[13];

    trace_user_do_rt_sigreturn(env, frame_addr);

    if (frame_addr & 7) {

        goto badframe;

    }

    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {

        goto badframe;

    }

    if (do_sigframe_return_v2(env, frame_addr, &frame->uc)) {

        goto badframe;

    }

    unlock_user_struct(frame, frame_addr, 0);

    return -TARGET_QEMU_ESIGRETURN;

badframe:

    unlock_user_struct(frame, frame_addr, 0);

    force_sig(TARGET_SIGSEGV /* , current */);

    return 0;

}


static void vp8_h_loop_filter_simple_c(uint8_t *dst, ptrdiff_t stride, int flim)

{

    int i;

    for (i = 0; i < 16; i++)

        if (simple_limit(dst + i * stride, 1, flim))

            filter_common(dst + i * stride, 1, 1);

}


static void gain_scale(G723_1_Context *p, int16_t * buf, int energy)

{

    int num, denom, gain, bits1, bits2;

    int i;

    num   = energy;

    denom = 0;

    for (i = 0; i < SUBFRAME_LEN; i++) {

        int64_t temp = buf[i] >> 2;

        temp  = av_clipl_int32(MUL64(temp, temp) << 1);

        denom = av_clipl_int32(denom + temp);

    }

    if (num && denom) {

        bits1   = normalize_bits(num,   31);

        bits2   = normalize_bits(denom, 31);

        num     = num << bits1 >> 1;

        denom <<= bits2;

        bits2 = 5 + bits1 - bits2;

        bits2 = FFMAX(0, bits2);

        gain = (num >> 1) / (denom >> 16);

        gain = square_root(gain << 16 >> bits2);

    } else {

        gain = 1 << 12;

    }

    for (i = 0; i < SUBFRAME_LEN; i++) {

        p->pf_gain = (15 * p->pf_gain + gain + (1 << 3)) >> 4;

        buf[i]     = av_clip_int16((buf[i] * (p->pf_gain + (p->pf_gain >> 4)) +

                                   (1 << 10)) >> 11);

    }

}


void OPPROTO op_store_msr_32 (void)

{

    ppc_store_msr_32(env, T0);

    RETURN();

}


int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr orig_vaddr,

                              int rw, int mmu_idx)

{

    S390CPU *cpu = S390_CPU(cs);

    CPUS390XState *env = &cpu->env;

    uint64_t asc = cpu_mmu_idx_to_asc(mmu_idx);

    target_ulong vaddr, raddr;

    int prot;

    DPRINTF("%s: address 0x%" VADDR_PRIx " rw %d mmu_idx %d\n",

            __func__, orig_vaddr, rw, mmu_idx);

    orig_vaddr &= TARGET_PAGE_MASK;

    vaddr = orig_vaddr;

    /* 31-Bit mode */

    if (!(env->psw.mask & PSW_MASK_64)) {

        vaddr &= 0x7fffffff;

    }

    if (mmu_translate(env, vaddr, rw, asc, &raddr, &prot, true)) {

        /* Translation ended in exception */

        return 1;

    }

    /* check out of RAM access */

    if (raddr > ram_size) {

        DPRINTF("%s: raddr %" PRIx64 " > ram_size %" PRIx64 "\n", __func__,

                (uint64_t)raddr, (uint64_t)ram_size);

        trigger_pgm_exception(env, PGM_ADDRESSING, ILEN_AUTO);

        return 1;

    }

    qemu_log_mask(CPU_LOG_MMU, "%s: set tlb %" PRIx64 " -> %" PRIx64 " (%x)\n",

            __func__, (uint64_t)vaddr, (uint64_t)raddr, prot);

    tlb_set_page(cs, orig_vaddr, raddr, prot,

                 mmu_idx, TARGET_PAGE_SIZE);

    return 0;

}


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;

    av_dlog(s, "wanted_pts=%0.6f\n", wanted_pts / 1000000.0);

    /* find the position using linear interpolation (better than

       dichotomy in typical cases) */

    if (ffm->write_index && ffm->write_index < ffm->file_size) {

        if (get_dts(s, FFM_PACKET_SIZE) < wanted_pts) {

            pos_min = FFM_PACKET_SIZE;

            pos_max = ffm->write_index - FFM_PACKET_SIZE;

        } else {

            pos_min = ffm->write_index;

            pos_max = ffm->file_size - FFM_PACKET_SIZE;

        }

    } else {

        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);

        if (pts_min > wanted_pts || pts_max < wanted_pts) {

            pos = pts_min > wanted_pts ? pos_min : pos_max;

            goto found;

        }

        /* 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:

    if (ffm_seek1(s, pos) < 0)

        return -1;

    /* 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 void openpic_load_IRQ_queue(QEMUFile* f, IRQ_queue_t *q)

{

    unsigned int i;

    for (i = 0; i < BF_WIDTH(MAX_IRQ); i++)

        qemu_get_be32s(f, &q->queue[i]);

    qemu_get_sbe32s(f, &q->next);

    qemu_get_sbe32s(f, &q->priority);

}


static void rtas_set_time_of_day(sPAPREnvironment *spapr,

                                 uint32_t token, uint32_t nargs,

                                 target_ulong args,

                                 uint32_t nret, target_ulong rets)

{

    struct tm tm;

    tm.tm_year = rtas_ld(args, 0) - 1900;

    tm.tm_mon = rtas_ld(args, 1) - 1;

    tm.tm_mday = rtas_ld(args, 2);

    tm.tm_hour = rtas_ld(args, 3);

    tm.tm_min = rtas_ld(args, 4);

    tm.tm_sec = rtas_ld(args, 5);

    /* Just generate a monitor event for the change */

    rtc_change_mon_event(&tm);

    spapr->rtc_offset = qemu_timedate_diff(&tm);

    rtas_st(rets, 0, 0); /* Success */

}


void virtqueue_map(VirtIODevice *vdev, VirtQueueElement *elem)

{

    virtqueue_map_iovec(vdev, elem->in_sg, elem->in_addr, &elem->in_num,

                        MIN(ARRAY_SIZE(elem->in_sg), ARRAY_SIZE(elem->in_addr)),

                        1);

    virtqueue_map_iovec(vdev, elem->out_sg, elem->out_addr, &elem->out_num,

                        MIN(ARRAY_SIZE(elem->out_sg),

                        ARRAY_SIZE(elem->out_addr)),

                        0);

}


static int qed_write_header_sync(BDRVQEDState *s)

{

    QEDHeader le;

    int ret;

    qed_header_cpu_to_le(&s->header, &le);

    ret = bdrv_pwrite(s->bs->file, 0, &le, sizeof(le));

    if (ret != sizeof(le)) {

        return ret;

    }

    return 0;

}