static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,

                          QEMUMachineInitArgs *args)

{

    const char *cpu_model = args->cpu_model;

    unsigned int i;

    void *iommu, *espdma, *ledma, *nvram;

    qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS],

        espdma_irq, ledma_irq;

    qemu_irq esp_reset, dma_enable;

    qemu_irq fdc_tc;

    qemu_irq *cpu_halt;

    unsigned long kernel_size;

    DriveInfo *fd[MAX_FD];

    FWCfgState *fw_cfg;

    unsigned int num_vsimms;

    /* init CPUs */

    if (!cpu_model)

        cpu_model = hwdef->default_cpu_model;

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

        cpu_devinit(cpu_model, i, hwdef->slavio_base, &cpu_irqs[i]);

    }

    for (i = smp_cpus; i < MAX_CPUS; i++)

        cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);

    /* set up devices */

    ram_init(0, args->ram_size, hwdef->max_mem);

    /* models without ECC don't trap when missing ram is accessed */

    if (!hwdef->ecc_base) {

        empty_slot_init(args->ram_size, hwdef->max_mem - args->ram_size);

    }

    prom_init(hwdef->slavio_base, bios_name);

    slavio_intctl = slavio_intctl_init(hwdef->intctl_base,

                                       hwdef->intctl_base + 0x10000ULL,

                                       cpu_irqs);

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

        slavio_irq[i] = qdev_get_gpio_in(slavio_intctl, i);

    }

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

        slavio_cpu_irq[i] = qdev_get_gpio_in(slavio_intctl, 32 + i);

    }

    if (hwdef->idreg_base) {

        idreg_init(hwdef->idreg_base);

    }

    if (hwdef->afx_base) {

        afx_init(hwdef->afx_base);

    }

    iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,

                       slavio_irq[30]);

    if (hwdef->iommu_pad_base) {

        /* On the real hardware (SS-5, LX) the MMU is not padded, but aliased.

           Software shouldn't use aliased addresses, neither should it crash

           when does. Using empty_slot instead of aliasing can help with

           debugging such accesses */

        empty_slot_init(hwdef->iommu_pad_base,hwdef->iommu_pad_len);

    }

    espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[18],

                              iommu, &espdma_irq, 0);

    ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,

                             slavio_irq[16], iommu, &ledma_irq, 1);

    if (graphic_depth != 8 && graphic_depth != 24) {

        fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);

        exit (1);

    }

    num_vsimms = 0;

    if (num_vsimms == 0) {

        tcx_init(hwdef->tcx_base, 0x00100000, graphic_width, graphic_height,

                 graphic_depth);

    }

    for (i = num_vsimms; i < MAX_VSIMMS; i++) {

        /* vsimm registers probed by OBP */

        if (hwdef->vsimm[i].reg_base) {

            empty_slot_init(hwdef->vsimm[i].reg_base, 0x2000);

        }

    }

    if (hwdef->sx_base) {

        empty_slot_init(hwdef->sx_base, 0x2000);

    }

    lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq);

    nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, 0x2000, 8);

    slavio_timer_init_all(hwdef->counter_base, slavio_irq[19], slavio_cpu_irq, smp_cpus);

    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[14],

                              display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);

    /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device

       Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */

    escc_init(hwdef->serial_base, slavio_irq[15], slavio_irq[15],

              serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);

    cpu_halt = qemu_allocate_irqs(cpu_halt_signal, NULL, 1);

    if (hwdef->apc_base) {

        apc_init(hwdef->apc_base, cpu_halt[0]);

    }

    if (hwdef->fd_base) {

        /* there is zero or one floppy drive */

        memset(fd, 0, sizeof(fd));

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

        sun4m_fdctrl_init(slavio_irq[22], hwdef->fd_base, fd,

                          &fdc_tc);

    } else {

        fdc_tc = *qemu_allocate_irqs(dummy_fdc_tc, NULL, 1);

    }

    slavio_misc_init(hwdef->slavio_base, hwdef->aux1_base, hwdef->aux2_base,

                     slavio_irq[30], fdc_tc);

    if (drive_get_max_bus(IF_SCSI) > 0) {

        fprintf(stderr, "qemu: too many SCSI bus\n");

        exit(1);

    }

    esp_init(hwdef->esp_base, 2,

             espdma_memory_read, espdma_memory_write,

             espdma, espdma_irq, &esp_reset, &dma_enable);

    qdev_connect_gpio_out(espdma, 0, esp_reset);

    qdev_connect_gpio_out(espdma, 1, dma_enable);

    if (hwdef->cs_base) {

        sysbus_create_simple("SUNW,CS4231", hwdef->cs_base,

                             slavio_irq[5]);

    }

    if (hwdef->dbri_base) {

        /* ISDN chip with attached CS4215 audio codec */

        /* prom space */

        empty_slot_init(hwdef->dbri_base+0x1000, 0x30);

        /* reg space */

        empty_slot_init(hwdef->dbri_base+0x10000, 0x100);

    }

    if (hwdef->bpp_base) {

        /* parallel port */

        empty_slot_init(hwdef->bpp_base, 0x20);

    }

    kernel_size = sun4m_load_kernel(args->kernel_filename,

                                    args->initrd_filename,

                                    args->ram_size);

    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, args->kernel_cmdline,

               args->boot_device, args->ram_size, kernel_size, graphic_width,

               graphic_height, graphic_depth, hwdef->nvram_machine_id,

               "Sun4m");

    if (hwdef->ecc_base)

        ecc_init(hwdef->ecc_base, slavio_irq[28],

                 hwdef->ecc_version);

    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);

    fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);

    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);

    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);

    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);

    fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth);

    fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_WIDTH, graphic_width);

    fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_HEIGHT, graphic_height);

    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);

    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);

    if (args->kernel_cmdline) {

        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);

        pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE,

                         args->kernel_cmdline);

        fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, args->kernel_cmdline);

        fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,

                       strlen(args->kernel_cmdline) + 1);

    } else {

        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);

        fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0);

    }

    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);

    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0); // not used

    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, args->boot_device[0]);

    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);

}


static inline void gen_op_eval_ble(TCGv dst, TCGv_i32 src)

{

    gen_mov_reg_N(cpu_tmp0, src);

    gen_mov_reg_V(dst, src);

    tcg_gen_xor_tl(dst, dst, cpu_tmp0);

    gen_mov_reg_Z(cpu_tmp0, src);

    tcg_gen_or_tl(dst, dst, cpu_tmp0);

}


static void colo_compare_finalize(Object *obj)

{

    CompareState *s = COLO_COMPARE(obj);

    qemu_chr_fe_deinit(&s->chr_pri_in, false);

    qemu_chr_fe_deinit(&s->chr_sec_in, false);

    qemu_chr_fe_deinit(&s->chr_out, false);

    g_main_loop_quit(s->compare_loop);

    qemu_thread_join(&s->thread);

    /* Release all unhandled packets after compare thead exited */

    g_queue_foreach(&s->conn_list, colo_flush_packets, s);

    g_queue_clear(&s->conn_list);

    g_hash_table_destroy(s->connection_track_table);

    g_free(s->pri_indev);

    g_free(s->sec_indev);

    g_free(s->outdev);

}


static int exec_close(MigrationState *s)

{

    int ret = 0;

    DPRINTF("exec_close\n");

    ret = qemu_fclose(s->opaque);

    s->opaque = NULL;

    s->fd = -1;

    if (ret >= 0 && !(WIFEXITED(ret) && WEXITSTATUS(ret) == 0)) {

        /* close succeeded, but non-zero exit code: */

        ret = -EIO; /* fake errno value */

    }

    return ret;

}


static int megasas_handle_abort(MegasasState *s, MegasasCmd *cmd)

{

    uint64_t abort_ctx = le64_to_cpu(cmd->frame->abort.abort_context);

    target_phys_addr_t abort_addr, addr_hi, addr_lo;

    MegasasCmd *abort_cmd;

    addr_hi = le32_to_cpu(cmd->frame->abort.abort_mfi_addr_hi);

    addr_lo = le32_to_cpu(cmd->frame->abort.abort_mfi_addr_lo);

    abort_addr = ((uint64_t)addr_hi << 32) | addr_lo;

    abort_cmd = megasas_lookup_frame(s, abort_addr);

    if (!abort_cmd) {

        trace_megasas_abort_no_cmd(cmd->index, abort_ctx);

        s->event_count++;

        return MFI_STAT_OK;

    }

    if (!megasas_use_queue64(s)) {

        abort_ctx &= (uint64_t)0xFFFFFFFF;

    }

    if (abort_cmd->context != abort_ctx) {

        trace_megasas_abort_invalid_context(cmd->index, abort_cmd->index,

                                            abort_cmd->context);

        s->event_count++;

        return MFI_STAT_ABORT_NOT_POSSIBLE;

    }

    trace_megasas_abort_frame(cmd->index, abort_cmd->index);

    megasas_abort_command(abort_cmd);

    if (!s->event_cmd || abort_cmd != s->event_cmd) {

        s->event_cmd = NULL;

    }

    s->event_count++;

    return MFI_STAT_OK;

}


static bool aio_epoll_enabled(AioContext *ctx)

{

    /* Fall back to ppoll when external clients are disabled. */

    return !aio_external_disabled(ctx) && ctx->epoll_enabled;

}


av_cold void ff_h264_decode_init_vlc(void){

    static int done = 0;

    if (!done) {

        int i;

        int offset;

        done = 1;

        chroma_dc_coeff_token_vlc.table = chroma_dc_coeff_token_vlc_table;

        chroma_dc_coeff_token_vlc.table_allocated = chroma_dc_coeff_token_vlc_table_size;

        init_vlc(&chroma_dc_coeff_token_vlc, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 4*5,

                 &chroma_dc_coeff_token_len [0], 1, 1,

                 &chroma_dc_coeff_token_bits[0], 1, 1,

                 INIT_VLC_USE_NEW_STATIC);

        chroma422_dc_coeff_token_vlc.table = chroma422_dc_coeff_token_vlc_table;

        chroma422_dc_coeff_token_vlc.table_allocated = chroma422_dc_coeff_token_vlc_table_size;

        init_vlc(&chroma422_dc_coeff_token_vlc, CHROMA422_DC_COEFF_TOKEN_VLC_BITS, 4*9,

                 &chroma422_dc_coeff_token_len [0], 1, 1,

                 &chroma422_dc_coeff_token_bits[0], 1, 1,

                 INIT_VLC_USE_NEW_STATIC);

        offset = 0;

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

            coeff_token_vlc[i].table = coeff_token_vlc_tables+offset;

            coeff_token_vlc[i].table_allocated = coeff_token_vlc_tables_size[i];

            init_vlc(&coeff_token_vlc[i], COEFF_TOKEN_VLC_BITS, 4*17,

                     &coeff_token_len [i][0], 1, 1,

                     &coeff_token_bits[i][0], 1, 1,

                     INIT_VLC_USE_NEW_STATIC);

            offset += coeff_token_vlc_tables_size[i];

        }

        /*

         * This is a one time safety check to make sure that

         * the packed static coeff_token_vlc table sizes

         * were initialized correctly.

         */

        av_assert0(offset == FF_ARRAY_ELEMS(coeff_token_vlc_tables));

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

            chroma_dc_total_zeros_vlc[i].table = chroma_dc_total_zeros_vlc_tables[i];

            chroma_dc_total_zeros_vlc[i].table_allocated = chroma_dc_total_zeros_vlc_tables_size;

            init_vlc(&chroma_dc_total_zeros_vlc[i],

                     CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 4,

                     &chroma_dc_total_zeros_len [i][0], 1, 1,

                     &chroma_dc_total_zeros_bits[i][0], 1, 1,

                     INIT_VLC_USE_NEW_STATIC);

        }

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

            chroma422_dc_total_zeros_vlc[i].table = chroma422_dc_total_zeros_vlc_tables[i];

            chroma422_dc_total_zeros_vlc[i].table_allocated = chroma422_dc_total_zeros_vlc_tables_size;

            init_vlc(&chroma422_dc_total_zeros_vlc[i],

                     CHROMA422_DC_TOTAL_ZEROS_VLC_BITS, 8,

                     &chroma422_dc_total_zeros_len [i][0], 1, 1,

                     &chroma422_dc_total_zeros_bits[i][0], 1, 1,

                     INIT_VLC_USE_NEW_STATIC);

        }

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

            total_zeros_vlc[i].table = total_zeros_vlc_tables[i];

            total_zeros_vlc[i].table_allocated = total_zeros_vlc_tables_size;

            init_vlc(&total_zeros_vlc[i],

                     TOTAL_ZEROS_VLC_BITS, 16,

                     &total_zeros_len [i][0], 1, 1,

                     &total_zeros_bits[i][0], 1, 1,

                     INIT_VLC_USE_NEW_STATIC);

        }

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

            run_vlc[i].table = run_vlc_tables[i];

            run_vlc[i].table_allocated = run_vlc_tables_size;

            init_vlc(&run_vlc[i],

                     RUN_VLC_BITS, 7,

                     &run_len [i][0], 1, 1,

                     &run_bits[i][0], 1, 1,

                     INIT_VLC_USE_NEW_STATIC);

        }

        run7_vlc.table = run7_vlc_table,

        run7_vlc.table_allocated = run7_vlc_table_size;

        init_vlc(&run7_vlc, RUN7_VLC_BITS, 16,

                 &run_len [6][0], 1, 1,

                 &run_bits[6][0], 1, 1,

                 INIT_VLC_USE_NEW_STATIC);

        init_cavlc_level_tab();

    }

}


static inline void RENAME(yuvPlanartouyvy)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst,

	unsigned int width, unsigned int height,

	int lumStride, int chromStride, int dstStride, int vertLumPerChroma)

{

	unsigned y;

	const unsigned chromWidth= width>>1;

	for(y=0; y<height; y++)

	{

#ifdef HAVE_MMX

//FIXME handle 2 lines a once (fewer prefetch, reuse some chrom, but very likely limited by mem anyway)

		asm volatile(

			"xor %%"REG_a", %%"REG_a"	\n\t"

			".balign 16			\n\t"

			"1:				\n\t"

			PREFETCH" 32(%1, %%"REG_a", 2)	\n\t"

			PREFETCH" 32(%2, %%"REG_a")	\n\t"

			PREFETCH" 32(%3, %%"REG_a")	\n\t"

			"movq (%2, %%"REG_a"), %%mm0	\n\t" // U(0)

			"movq %%mm0, %%mm2		\n\t" // U(0)

			"movq (%3, %%"REG_a"), %%mm1	\n\t" // V(0)

			"punpcklbw %%mm1, %%mm0		\n\t" // UVUV UVUV(0)

			"punpckhbw %%mm1, %%mm2		\n\t" // UVUV UVUV(8)

			"movq (%1, %%"REG_a",2), %%mm3	\n\t" // Y(0)

			"movq 8(%1, %%"REG_a",2), %%mm5	\n\t" // Y(8)

			"movq %%mm0, %%mm4		\n\t" // Y(0)

			"movq %%mm2, %%mm6		\n\t" // Y(8)

			"punpcklbw %%mm3, %%mm0		\n\t" // YUYV YUYV(0)

			"punpckhbw %%mm3, %%mm4		\n\t" // YUYV YUYV(4)

			"punpcklbw %%mm5, %%mm2		\n\t" // YUYV YUYV(8)

			"punpckhbw %%mm5, %%mm6		\n\t" // YUYV YUYV(12)

			MOVNTQ" %%mm0, (%0, %%"REG_a", 4)\n\t"

			MOVNTQ" %%mm4, 8(%0, %%"REG_a", 4)\n\t"

			MOVNTQ" %%mm2, 16(%0, %%"REG_a", 4)\n\t"

			MOVNTQ" %%mm6, 24(%0, %%"REG_a", 4)\n\t"

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

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

			" jb 1b				\n\t"

			::"r"(dst), "r"(ysrc), "r"(usrc), "r"(vsrc), "g" ((long)chromWidth)

			: "%"REG_a

		);

#else

//FIXME adapt the alpha asm code from yv12->yuy2

#if __WORDSIZE >= 64

		int i;

		uint64_t *ldst = (uint64_t *) dst;

		const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;

		for(i = 0; i < chromWidth; i += 2){

			uint64_t k, l;

			k = uc[0] + (yc[0] << 8) +

			    (vc[0] << 16) + (yc[1] << 24);

			l = uc[1] + (yc[2] << 8) +

			    (vc[1] << 16) + (yc[3] << 24);

			*ldst++ = k + (l << 32);

			yc += 4;

			uc += 2;

			vc += 2;

		}

#else

		int i, *idst = (int32_t *) dst;

		const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;

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

#ifdef WORDS_BIGENDIAN

			*idst++ = (uc[0] << 24)+ (yc[0] << 16) +

			    (vc[0] << 8) + (yc[1] << 0);

#else

			*idst++ = uc[0] + (yc[0] << 8) +

			    (vc[0] << 16) + (yc[1] << 24);

#endif

			yc += 2;

			uc++;

			vc++;

		}

#endif

#endif

		if((y&(vertLumPerChroma-1))==(vertLumPerChroma-1) )

		{

			usrc += chromStride;

			vsrc += chromStride;

		}

		ysrc += lumStride;

		dst += dstStride;

	}

#ifdef HAVE_MMX

asm(    EMMS" \n\t"

        SFENCE" \n\t"

        :::"memory");

#endif

}


static inline int get_lowest_part_list_y(H264Context *h, Picture *pic, int n,

                                         int height, int y_offset, int list)

{

    int raw_my        = h->mv_cache[list][scan8[n]][1];

    int filter_height = (raw_my & 3) ? 2 : 0;

    int full_my       = (raw_my >> 2) + y_offset;

    int top           = full_my - filter_height;

    int bottom        = full_my + filter_height + height;

    return FFMAX(abs(top), bottom);

}


int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,

                      uint8_t* buf, int buf_size)

{

    int size, i;

    uint8_t *ppcm[4] = {0};

    if (buf_size < DV_PROFILE_BYTES ||

        !(c->sys = avpriv_dv_frame_profile(c->sys, buf, buf_size)) ||

        buf_size < c->sys->frame_size) {

          return -1;   /* Broken frame, or not enough data */

    }

    /* Queueing audio packet */

    /* FIXME: in case of no audio/bad audio we have to do something */

    size = dv_extract_audio_info(c, buf);

    for (i = 0; i < c->ach; i++) {

       c->audio_pkt[i].size = size;

       c->audio_pkt[i].pts  = c->abytes * 30000*8 / c->ast[i]->codec->bit_rate;

       ppcm[i] = c->audio_buf[i];

    }

    dv_extract_audio(buf, ppcm, c->sys);

    /* We work with 720p frames split in half, thus even frames have

     * channels 0,1 and odd 2,3. */

    if (c->sys->height == 720) {

        if (buf[1] & 0x0C) {

            c->audio_pkt[2].size = c->audio_pkt[3].size = 0;

        } else {

            c->audio_pkt[0].size = c->audio_pkt[1].size = 0;

            c->abytes += size;

        }

    } else {

        c->abytes += size;

    }

    /* Now it's time to return video packet */

    size = dv_extract_video_info(c, buf);

    av_init_packet(pkt);

    pkt->data         = buf;

    pkt->size         = size;

    pkt->flags       |= AV_PKT_FLAG_KEY;

    pkt->stream_index = c->vst->id;

    pkt->pts          = c->frames;

    c->frames++;

    return size;

}


static void fw_cfg_io_class_init(ObjectClass *klass, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = fw_cfg_io_realize;

    dc->props = fw_cfg_io_properties;

}


static int net_socket_listen_init(VLANState *vlan,

                                  const char *model,

                                  const char *name,

                                  const char *host_str)

{

    NetSocketListenState *s;

    int fd, val, ret;

    struct sockaddr_in saddr;

    if (parse_host_port(&saddr, host_str) < 0)

        return -1;

    s = g_malloc0(sizeof(NetSocketListenState));

    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);

    if (fd < 0) {

        perror("socket");

        g_free(s);

        return -1;

    }

    socket_set_nonblock(fd);

    /* allow fast reuse */

    val = 1;

    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));

    ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));

    if (ret < 0) {

        perror("bind");

        g_free(s);

        return -1;

    }

    ret = listen(fd, 0);

    if (ret < 0) {

        perror("listen");

        g_free(s);

        return -1;

    }

    s->vlan = vlan;

    s->model = g_strdup(model);

    s->name = name ? g_strdup(name) : NULL;

    s->fd = fd;

    qemu_set_fd_handler(fd, net_socket_accept, NULL, s);

    return 0;

}


static void e1000e_pci_realize(PCIDevice *pci_dev, Error **errp)

{

    static const uint16_t e1000e_pmrb_offset = 0x0C8;

    static const uint16_t e1000e_pcie_offset = 0x0E0;

    static const uint16_t e1000e_aer_offset =  0x100;

    static const uint16_t e1000e_dsn_offset =  0x140;

    E1000EState *s = E1000E(pci_dev);

    uint8_t *macaddr;

    int ret;

    trace_e1000e_cb_pci_realize();

    pci_dev->config_write = e1000e_write_config;

    pci_dev->config[PCI_CACHE_LINE_SIZE] = 0x10;

    pci_dev->config[PCI_INTERRUPT_PIN] = 1;

    pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID, s->subsys_ven);

    pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID, s->subsys);

    s->subsys_ven_used = s->subsys_ven;

    s->subsys_used = s->subsys;

    /* Define IO/MMIO regions */

    memory_region_init_io(&s->mmio, OBJECT(s), &mmio_ops, s,

                          "e1000e-mmio", E1000E_MMIO_SIZE);

    pci_register_bar(pci_dev, E1000E_MMIO_IDX,

                     PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);

    /*

     * We provide a dummy implementation for the flash BAR

     * for drivers that may theoretically probe for its presence.

     */

    memory_region_init(&s->flash, OBJECT(s),

                       "e1000e-flash", E1000E_FLASH_SIZE);

    pci_register_bar(pci_dev, E1000E_FLASH_IDX,

                     PCI_BASE_ADDRESS_SPACE_MEMORY, &s->flash);

    memory_region_init_io(&s->io, OBJECT(s), &io_ops, s,

                          "e1000e-io", E1000E_IO_SIZE);

    pci_register_bar(pci_dev, E1000E_IO_IDX,

                     PCI_BASE_ADDRESS_SPACE_IO, &s->io);

    memory_region_init(&s->msix, OBJECT(s), "e1000e-msix",

                       E1000E_MSIX_SIZE);

    pci_register_bar(pci_dev, E1000E_MSIX_IDX,

                     PCI_BASE_ADDRESS_SPACE_MEMORY, &s->msix);

    /* Create networking backend */

    qemu_macaddr_default_if_unset(&s->conf.macaddr);

    macaddr = s->conf.macaddr.a;

    e1000e_init_msix(s);

    if (pcie_endpoint_cap_v1_init(pci_dev, e1000e_pcie_offset) < 0) {

        hw_error("Failed to initialize PCIe capability");

    }

    ret = msi_init(PCI_DEVICE(s), 0xD0, 1, true, false, NULL);

    if (ret) {

        trace_e1000e_msi_init_fail(ret);

    }

    if (e1000e_add_pm_capability(pci_dev, e1000e_pmrb_offset,

                                  PCI_PM_CAP_DSI) < 0) {

        hw_error("Failed to initialize PM capability");

    }

    if (pcie_aer_init(pci_dev, e1000e_aer_offset, PCI_ERR_SIZEOF) < 0) {

        hw_error("Failed to initialize AER capability");

    }

    pcie_dev_ser_num_init(pci_dev, e1000e_dsn_offset,

                          e1000e_gen_dsn(macaddr));

    e1000e_init_net_peer(s, pci_dev, macaddr);

    /* Initialize core */

    e1000e_core_realize(s);

    e1000e_core_pci_realize(&s->core,

                            e1000e_eeprom_template,

                            sizeof(e1000e_eeprom_template),

                            macaddr);

}


int ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *band_psd,
                               int start, int end, int fast_gain, int is_lfe,
                               int dba_mode, int dba_nsegs, uint8_t *dba_offsets,
                               uint8_t *dba_lengths, uint8_t *dba_values,
                               int16_t *mask)
{
    int16_t excite[AC3_CRITICAL_BANDS]; /* excitation */
    int band;
    int band_start, band_end, begin, end1;
    int lowcomp, fastleak, slowleak;
    /* excitation function */
    band_start = ff_ac3_bin_to_band_tab[start];
    band_end   = ff_ac3_bin_to_band_tab[end-1] + 1;
    if (band_start == 0) {
        lowcomp = 0;
        lowcomp = calc_lowcomp1(lowcomp, band_psd[0], band_psd[1], 384);
        excite[0] = band_psd[0] - fast_gain - lowcomp;
        lowcomp = calc_lowcomp1(lowcomp, band_psd[1], band_psd[2], 384);
        excite[1] = band_psd[1] - fast_gain - lowcomp;
        begin = 7;
        for (band = 2; band < 7; band++) {
            if (!(is_lfe && band == 6))
                lowcomp = calc_lowcomp1(lowcomp, band_psd[band], band_psd[band+1], 384);
            fastleak = band_psd[band] - fast_gain;
            slowleak = band_psd[band] - s->slow_gain;
            excite[band] = fastleak - lowcomp;
            if (!(is_lfe && band == 6)) {
                if (band_psd[band] <= band_psd[band+1]) {
                    begin = band + 1;
                    break;
                }
            }
        }
        end1 = FFMIN(band_end, 22);
        for (band = begin; band < end1; band++) {
            if (!(is_lfe && band == 6))
                lowcomp = calc_lowcomp(lowcomp, band_psd[band], band_psd[band+1], band);
            fastleak = FFMAX(fastleak - s->fast_decay, band_psd[band] - fast_gain);
            slowleak = FFMAX(slowleak - s->slow_decay, band_psd[band] - s->slow_gain);
            excite[band] = FFMAX(fastleak - lowcomp, slowleak);
        }
        begin = 22;
    } else {
        /* coupling channel */
        begin = band_start;
        fastleak = (s->cpl_fast_leak << 8) + 768;
        slowleak = (s->cpl_slow_leak << 8) + 768;
    }
    for (band = begin; band < band_end; band++) {
        fastleak = FFMAX(fastleak - s->fast_decay, band_psd[band] - fast_gain);
        slowleak = FFMAX(slowleak - s->slow_decay, band_psd[band] - s->slow_gain);
        excite[band] = FFMAX(fastleak, slowleak);
    }
    /* compute masking curve */
    for (band = band_start; band < band_end; band++) {
        int tmp = s->db_per_bit - band_psd[band];
        if (tmp > 0) {
            excite[band] += tmp >> 2;
        }
        mask[band] = FFMAX(ff_ac3_hearing_threshold_tab[band >> s->sr_shift][s->sr_code], excite[band]);
    }
    /* delta bit allocation */
    if (dba_mode == DBA_REUSE || dba_mode == DBA_NEW) {
        int i, seg, delta;
        if (dba_nsegs > 8)
            return -1;
        band = band_start;
        for (seg = 0; seg < dba_nsegs; seg++) {
            band += dba_offsets[seg];
            if (band >= AC3_CRITICAL_BANDS || dba_lengths[seg] > AC3_CRITICAL_BANDS-band)
                return -1;
            if (dba_values[seg] >= 4) {
                delta = (dba_values[seg] - 3) * 128;
            } else {
                delta = (dba_values[seg] - 4) * 128;
            }
            for (i = 0; i < dba_lengths[seg]; i++) {
                mask[band++] += delta;
            }
        }
    }
    return 0;
}


int v9fs_remove_xattr(FsContext *ctx,

                      const char *path, const char *name)

{

    XattrOperations *xops = get_xattr_operations(ctx->xops, name);

    if (xops) {

        return xops->removexattr(ctx, path, name);

    }

    errno = -EOPNOTSUPP;

    return -1;

}


static void gen_rfsvc(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    gen_helper_rfsvc(cpu_env);

    gen_sync_exception(ctx);

#endif

}


static void pc_init1(QEMUMachineInitArgs *args,

                     int pci_enabled,

                     int kvmclock_enabled)

{

    MemoryRegion *system_memory = get_system_memory();

    MemoryRegion *system_io = get_system_io();

    int i;

    ram_addr_t below_4g_mem_size, above_4g_mem_size;

    PCIBus *pci_bus;

    ISABus *isa_bus;

    PCII440FXState *i440fx_state;

    int piix3_devfn = -1;

    qemu_irq *cpu_irq;

    qemu_irq *gsi;

    qemu_irq *i8259;

    qemu_irq *smi_irq;

    GSIState *gsi_state;

    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];

    BusState *idebus[MAX_IDE_BUS];

    ISADevice *rtc_state;

    ISADevice *floppy;

    MemoryRegion *ram_memory;

    MemoryRegion *pci_memory;

    MemoryRegion *rom_memory;

    DeviceState *icc_bridge;

    FWCfgState *fw_cfg = NULL;

    PcGuestInfo *guest_info;

    if (xen_enabled() && xen_hvm_init(&ram_memory) != 0) {

        fprintf(stderr, "xen hardware virtual machine initialisation failed\n");

        exit(1);

    }

    icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE);

    object_property_add_child(qdev_get_machine(), "icc-bridge",

                              OBJECT(icc_bridge), NULL);

    pc_cpus_init(args->cpu_model, icc_bridge);

    if (kvm_enabled() && kvmclock_enabled) {

        kvmclock_create();

    }

    if (args->ram_size >= 0xe0000000) {

        above_4g_mem_size = args->ram_size - 0xe0000000;

        below_4g_mem_size = 0xe0000000;

    } else {

        above_4g_mem_size = 0;

        below_4g_mem_size = args->ram_size;

    }

    if (pci_enabled) {

        pci_memory = g_new(MemoryRegion, 1);

        memory_region_init(pci_memory, NULL, "pci", INT64_MAX);

        rom_memory = pci_memory;

    } else {

        pci_memory = NULL;

        rom_memory = system_memory;

    }

    guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size);

    guest_info->has_acpi_build = has_acpi_build;

    guest_info->has_pci_info = has_pci_info;

    guest_info->isapc_ram_fw = !pci_enabled;

    /* allocate ram and load rom/bios */

    if (!xen_enabled()) {

        fw_cfg = pc_memory_init(system_memory,

                       args->kernel_filename, args->kernel_cmdline,

                       args->initrd_filename,

                       below_4g_mem_size, above_4g_mem_size,

                       rom_memory, &ram_memory, guest_info);

    }

    gsi_state = g_malloc0(sizeof(*gsi_state));

    if (kvm_irqchip_in_kernel()) {

        kvm_pc_setup_irq_routing(pci_enabled);

        gsi = qemu_allocate_irqs(kvm_pc_gsi_handler, gsi_state,

                                 GSI_NUM_PINS);

    } else {

        gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);

    }

    if (pci_enabled) {

        pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, &isa_bus, gsi,

                              system_memory, system_io, args->ram_size,

                              below_4g_mem_size,

                              0x100000000ULL - below_4g_mem_size,

                              above_4g_mem_size,

                              pci_memory, ram_memory);

    } else {

        pci_bus = NULL;

        i440fx_state = NULL;

        isa_bus = isa_bus_new(NULL, system_io);

        no_hpet = 1;

    }

    isa_bus_irqs(isa_bus, gsi);

    if (kvm_irqchip_in_kernel()) {

        i8259 = kvm_i8259_init(isa_bus);

    } else if (xen_enabled()) {

        i8259 = xen_interrupt_controller_init();

    } else {

        cpu_irq = pc_allocate_cpu_irq();

        i8259 = i8259_init(isa_bus, cpu_irq[0]);

    }

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

        gsi_state->i8259_irq[i] = i8259[i];

    }

    if (pci_enabled) {

        ioapic_init_gsi(gsi_state, "i440fx");

    }

    qdev_init_nofail(icc_bridge);

    pc_register_ferr_irq(gsi[13]);

    pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL);

    /* init basic PC hardware */

    pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, xen_enabled());

    pc_nic_init(isa_bus, pci_bus);

    ide_drive_get(hd, MAX_IDE_BUS);

    if (pci_enabled) {

        PCIDevice *dev;

        if (xen_enabled()) {

            dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1);

        } else {

            dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);

        }

        idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");

        idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");

    } else {

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

            ISADevice *dev;

            dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i],

                               ide_irq[i],

                               hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);

            idebus[i] = qdev_get_child_bus(DEVICE(dev), "ide.0");

        }

    }

    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, args->boot_order,

                 floppy, idebus[0], idebus[1], rtc_state);

    if (pci_enabled && usb_enabled(false)) {

        pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci");

    }

    if (pci_enabled && acpi_enabled) {

        i2c_bus *smbus;

        smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);

        /* TODO: Populate SPD eeprom data.  */

        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,

                              gsi[9], *smi_irq,

                              kvm_enabled(), fw_cfg);

        smbus_eeprom_init(smbus, 8, NULL, 0);

    }

    if (pci_enabled) {

        pc_pci_device_init(pci_bus);

    }

    if (has_pvpanic) {

        pvpanic_init(isa_bus);

    }

}


static void v9fs_getattr(void *opaque)

{

    int32_t fid;

    size_t offset = 7;

    ssize_t retval = 0;

    struct stat stbuf;

    V9fsFidState *fidp;

    uint64_t request_mask;

    V9fsStatDotl v9stat_dotl;

    V9fsPDU *pdu = opaque;

    V9fsState *s = pdu->s;

    pdu_unmarshal(pdu, offset, "dq", &fid, &request_mask);

    fidp = get_fid(pdu, fid);

    if (fidp == NULL) {

        retval = -ENOENT;

        goto out_nofid;

    }

    /*

     * Currently we only support BASIC fields in stat, so there is no

     * need to look at request_mask.

     */

    retval = v9fs_co_lstat(pdu, &fidp->path, &stbuf);

    if (retval < 0) {

        goto out;

    }

    stat_to_v9stat_dotl(s, &stbuf, &v9stat_dotl);

    /*  fill st_gen if requested and supported by underlying fs */

    if (request_mask & P9_STATS_GEN) {

        retval = v9fs_co_st_gen(pdu, &fidp->path, stbuf.st_mode, &v9stat_dotl);

        if (retval < 0) {

            goto out;

        }

        v9stat_dotl.st_result_mask |= P9_STATS_GEN;

    }

    retval = offset;

    retval += pdu_marshal(pdu, offset, "A", &v9stat_dotl);

out:

    put_fid(pdu, fidp);

out_nofid:

    trace_v9fs_getattr_return(pdu->tag, pdu->id, v9stat_dotl.st_result_mask,

                              v9stat_dotl.st_mode, v9stat_dotl.st_uid,

                              v9stat_dotl.st_gid);

    complete_pdu(s, pdu, retval);

}


static int parse_audio_var(AVFormatContext *avctx, AVStream *st, const char *name, int size)

{

    AVIOContext *pb = avctx->pb;

    if (!strcmp(name, "__DIR_COUNT")) {

        st->nb_frames = var_read_int(pb, size);

    } else if (!strcmp(name, "AUDIO_FORMAT")) {

        st->codec->codec_id = var_read_int(pb, size);

    } else if (!strcmp(name, "COMPRESSION")) {

        st->codec->codec_tag = var_read_int(pb, size);

    } else if (!strcmp(name, "DEFAULT_VOL")) {

        var_read_metadata(avctx, name, size);

    } else if (!strcmp(name, "NUM_CHANNELS")) {

        st->codec->channels = var_read_int(pb, size);

        st->codec->channel_layout = (st->codec->channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;

    } else if (!strcmp(name, "SAMPLE_RATE")) {

        st->codec->sample_rate = var_read_int(pb, size);

        avpriv_set_pts_info(st, 33, 1, st->codec->sample_rate);

    } else if (!strcmp(name, "SAMPLE_WIDTH")) {

        st->codec->bits_per_coded_sample = var_read_int(pb, size) * 8;

    } else

        return -1;

    return 0;

}


static void gmc_mmx(uint8_t *dst, uint8_t *src,

                    int stride, int h, int ox, int oy,

                    int dxx, int dxy, int dyx, int dyy,

                    int shift, int r, int width, int height)

{

    const int w    = 8;

    const int ix   = ox  >> (16 + shift);

    const int iy   = oy  >> (16 + shift);

    const int oxs  = ox  >> 4;

    const int oys  = oy  >> 4;

    const int dxxs = dxx >> 4;

    const int dxys = dxy >> 4;

    const int dyxs = dyx >> 4;

    const int dyys = dyy >> 4;

    const uint16_t r4[4]   = { r, r, r, r };

    const uint16_t dxy4[4] = { dxys, dxys, dxys, dxys };

    const uint16_t dyy4[4] = { dyys, dyys, dyys, dyys };

    const uint64_t shift2  = 2 * shift;

#define MAX_STRIDE 4096U

#define MAX_H 8U

    uint8_t edge_buf[(MAX_H + 1) * MAX_STRIDE];

    int x, y;

    const int dxw = (dxx - (1 << (16 + shift))) * (w - 1);

    const int dyh = (dyy - (1 << (16 + shift))) * (h - 1);

    const int dxh = dxy * (h - 1);

    const int dyw = dyx * (w - 1);

    int need_emu  =  (unsigned) ix >= width  - w ||

                     (unsigned) iy >= height - h;

    if ( // non-constant fullpel offset (3% of blocks)

        ((ox ^ (ox + dxw)) | (ox ^ (ox + dxh)) | (ox ^ (ox + dxw + dxh)) |

         (oy ^ (oy + dyw)) | (oy ^ (oy + dyh)) | (oy ^ (oy + dyw + dyh))) >> (16 + shift) ||

        // uses more than 16 bits of subpel mv (only at huge resolution)

        (dxx | dxy | dyx | dyy) & 15 ||

        (need_emu && (h > MAX_H || stride > MAX_STRIDE))) {

        // FIXME could still use mmx for some of the rows

        ff_gmc_c(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy,

                 shift, r, width, height);

        return;

    }

    src += ix + iy * stride;

    if (need_emu) {

        ff_emulated_edge_mc_8(edge_buf, src, stride, stride, w + 1, h + 1, ix, iy, width, height);

        src = edge_buf;

    }

    __asm__ volatile (

        "movd         %0, %%mm6         \n\t"

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

        "punpcklwd %%mm6, %%mm6         \n\t"

        "punpcklwd %%mm6, %%mm6         \n\t"

        :: "r" (1 << shift));

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

        uint16_t dx4[4] = { oxs - dxys + dxxs * (x + 0),

                            oxs - dxys + dxxs * (x + 1),

                            oxs - dxys + dxxs * (x + 2),

                            oxs - dxys + dxxs * (x + 3) };

        uint16_t dy4[4] = { oys - dyys + dyxs * (x + 0),

                            oys - dyys + dyxs * (x + 1),

                            oys - dyys + dyxs * (x + 2),

                            oys - dyys + dyxs * (x + 3) };

        for (y = 0; y < h; y++) {

            __asm__ volatile (

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

                "movq      %1, %%mm5    \n\t"

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

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

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

                "movq   %%mm5, %1       \n\t"

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

                "psrlw    $12, %%mm5    \n\t"

                : "+m" (*dx4), "+m" (*dy4)

                : "m" (*dxy4), "m" (*dyy4));

            __asm__ volatile (

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

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

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

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

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

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

                "pmullw    %%mm1, %%mm0 \n\t" // (s - dx) * (s - dy)

                "pmullw    %%mm5, %%mm3 \n\t" // dx * dy

                "pmullw    %%mm5, %%mm2 \n\t" // (s - dx) * dy

                "pmullw    %%mm4, %%mm1 \n\t" // dx * (s - dy)

                "movd         %4, %%mm5 \n\t"

                "movd         %3, %%mm4 \n\t"

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

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

                "pmullw    %%mm5, %%mm3 \n\t" // src[1, 1] * dx * dy

                "pmullw    %%mm4, %%mm2 \n\t" // src[0, 1] * (s - dx) * dy

                "movd         %2, %%mm5 \n\t"

                "movd         %1, %%mm4 \n\t"

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

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

                "pmullw    %%mm5, %%mm1 \n\t" // src[1, 0] * dx * (s - dy)

                "pmullw    %%mm4, %%mm0 \n\t" // src[0, 0] * (s - dx) * (s - dy)

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

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

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

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

                "psrlw        %6, %%mm0 \n\t"

                "packuswb  %%mm0, %%mm0 \n\t"

                "movd      %%mm0, %0    \n\t"

                : "=m" (dst[x + y * stride])

                : "m" (src[0]), "m" (src[1]),

                  "m" (src[stride]), "m" (src[stride + 1]),

                  "m" (*r4), "m" (shift2));

            src += stride;

        }

        src += 4 - h * stride;

    }

}


static int decode_band_types(AACContext *ac, enum BandType band_type[120],

                             int band_type_run_end[120], GetBitContext *gb,

                             IndividualChannelStream *ics)

{

    int g, idx = 0;

    const int bits = (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) ? 3 : 5;

    for (g = 0; g < ics->num_window_groups; g++) {

        int k = 0;

        while (k < ics->max_sfb) {

            uint8_t sect_end = k;

            int sect_len_incr;

            int sect_band_type = get_bits(gb, 4);

            if (sect_band_type == 12) {

                av_log(ac->avctx, AV_LOG_ERROR, "invalid band type\n");

                return -1;

            }

            do {

                sect_len_incr = get_bits(gb, bits);

                sect_end += sect_len_incr;

                if (get_bits_left(gb) < 0) {

                    av_log(ac->avctx, AV_LOG_ERROR, overread_err);

                    return -1;

                }

                if (sect_end > ics->max_sfb) {

                    av_log(ac->avctx, AV_LOG_ERROR,

                           "Number of bands (%d) exceeds limit (%d).\n",

                           sect_end, ics->max_sfb);

                    return -1;

                }

            } while (sect_len_incr == (1 << bits) - 1);

            for (; k < sect_end; k++) {

                band_type        [idx]   = sect_band_type;

                band_type_run_end[idx++] = sect_end;

            }

        }

    }

    return 0;

}


target_ulong helper_ldr(CPUMIPSState *env, target_ulong arg1,

                        target_ulong arg2, int mem_idx)

{

    uint64_t tmp;

    tmp = do_lbu(env, arg2, mem_idx);

    arg1 = (arg1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;

    if (GET_LMASK64(arg2) >= 1) {

        tmp = do_lbu(env, GET_OFFSET(arg2, -1), mem_idx);

        arg1 = (arg1 & 0xFFFFFFFFFFFF00FFULL) | (tmp  << 8);

    }

    if (GET_LMASK64(arg2) >= 2) {

        tmp = do_lbu(env, GET_OFFSET(arg2, -2), mem_idx);

        arg1 = (arg1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);

    }

    if (GET_LMASK64(arg2) >= 3) {

        tmp = do_lbu(env, GET_OFFSET(arg2, -3), mem_idx);

        arg1 = (arg1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);

    }

    if (GET_LMASK64(arg2) >= 4) {

        tmp = do_lbu(env, GET_OFFSET(arg2, -4), mem_idx);

        arg1 = (arg1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);

    }

    if (GET_LMASK64(arg2) >= 5) {

        tmp = do_lbu(env, GET_OFFSET(arg2, -5), mem_idx);

        arg1 = (arg1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);

    }

    if (GET_LMASK64(arg2) >= 6) {

        tmp = do_lbu(env, GET_OFFSET(arg2, -6), mem_idx);

        arg1 = (arg1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);

    }

    if (GET_LMASK64(arg2) == 7) {

        tmp = do_lbu(env, GET_OFFSET(arg2, -7), mem_idx);

        arg1 = (arg1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);

    }

    return arg1;

}


int ff_hevc_decode_nal_sps(HEVCContext *s)

{

    const AVPixFmtDescriptor *desc;

    GetBitContext *gb = &s->HEVClc->gb;

    int ret = 0;

    unsigned int sps_id = 0;

    int log2_diff_max_min_transform_block_size;

    int bit_depth_chroma, start, vui_present, sublayer_ordering_info;

    int i;

    HEVCSPS *sps;

    AVBufferRef *sps_buf = av_buffer_allocz(sizeof(*sps));

    if (!sps_buf)

        return AVERROR(ENOMEM);

    sps = (HEVCSPS*)sps_buf->data;

    av_log(s->avctx, AV_LOG_DEBUG, "Decoding SPS\n");

    // Coded parameters

    sps->vps_id = get_bits(gb, 4);

    if (sps->vps_id >= MAX_VPS_COUNT) {

        av_log(s->avctx, AV_LOG_ERROR, "VPS id out of range: %d\n", sps->vps_id);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    if (!s->vps_list[sps->vps_id]) {

        av_log(s->avctx, AV_LOG_ERROR, "VPS %d does not exist\n",

               sps->vps_id);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    sps->max_sub_layers = get_bits(gb, 3) + 1;

    if (sps->max_sub_layers > MAX_SUB_LAYERS) {

        av_log(s->avctx, AV_LOG_ERROR, "sps_max_sub_layers out of range: %d\n",

               sps->max_sub_layers);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    skip_bits1(gb); // temporal_id_nesting_flag

    if (parse_ptl(s, &sps->ptl, sps->max_sub_layers) < 0)

        goto err;

    sps_id = get_ue_golomb_long(gb);

    if (sps_id >= MAX_SPS_COUNT) {

        av_log(s->avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", sps_id);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    sps->chroma_format_idc = get_ue_golomb_long(gb);

    if (sps->chroma_format_idc == 3)

        sps->separate_colour_plane_flag = get_bits1(gb);

    if (sps->separate_colour_plane_flag)

        sps->chroma_format_idc = 0;

    sps->width  = get_ue_golomb_long(gb);

    sps->height = get_ue_golomb_long(gb);

    if ((ret = av_image_check_size(sps->width,

                                   sps->height, 0, s->avctx)) < 0)

        goto err;

    if (get_bits1(gb)) { // pic_conformance_flag

        //TODO: * 2 is only valid for 420

        sps->pic_conf_win.left_offset   = get_ue_golomb_long(gb) * 2;

        sps->pic_conf_win.right_offset  = get_ue_golomb_long(gb) * 2;

        sps->pic_conf_win.top_offset    = get_ue_golomb_long(gb) * 2;

        sps->pic_conf_win.bottom_offset = get_ue_golomb_long(gb) * 2;

        if (s->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) {

            av_log(s->avctx, AV_LOG_DEBUG,

                   "discarding sps conformance window, "

                   "original values are l:%u r:%u t:%u b:%u\n",

                   sps->pic_conf_win.left_offset,

                   sps->pic_conf_win.right_offset,

                   sps->pic_conf_win.top_offset,

                   sps->pic_conf_win.bottom_offset);

            sps->pic_conf_win.left_offset   =

            sps->pic_conf_win.right_offset  =

            sps->pic_conf_win.top_offset    =

            sps->pic_conf_win.bottom_offset = 0;

        }

        sps->output_window = sps->pic_conf_win;

    }

    sps->bit_depth   = get_ue_golomb_long(gb) + 8;

    bit_depth_chroma = get_ue_golomb_long(gb) + 8;

    if (sps->chroma_format_idc && bit_depth_chroma != sps->bit_depth) {

        av_log(s->avctx, AV_LOG_ERROR,

               "Luma bit depth (%d) is different from chroma bit depth (%d), "

               "this is unsupported.\n",

               sps->bit_depth, bit_depth_chroma);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    switch (sps->bit_depth) {

    case 8:

        if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY8;

        if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P;

        if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P;

        if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P;

       break;

    case 9:

        if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY16;

        if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P9;

        if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P9;

        if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P9;

        break;

    case 10:

        if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY16;

        if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P10;

        if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P10;

        if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P10;

        break;

    case 12:

        if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY16;

        if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P12;

        if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P12;

        if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P12;

        break;

    default:

        av_log(s->avctx, AV_LOG_ERROR,

               "4:2:0, 4:2:2, 4:4:4 supports are currently specified for 8, 10 and 12 bits.\n");

        ret = AVERROR_PATCHWELCOME;

        goto err;

    }

    desc = av_pix_fmt_desc_get(sps->pix_fmt);

    if (!desc) {

        ret = AVERROR(EINVAL);

        goto err;

    }

    sps->hshift[0] = sps->vshift[0] = 0;

    sps->hshift[2] = sps->hshift[1] = desc->log2_chroma_w;

    sps->vshift[2] = sps->vshift[1] = desc->log2_chroma_h;

    sps->pixel_shift = sps->bit_depth > 8;

    sps->log2_max_poc_lsb = get_ue_golomb_long(gb) + 4;

    if (sps->log2_max_poc_lsb > 16) {

        av_log(s->avctx, AV_LOG_ERROR, "log2_max_pic_order_cnt_lsb_minus4 out range: %d\n",

               sps->log2_max_poc_lsb - 4);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    sublayer_ordering_info = get_bits1(gb);

    start = sublayer_ordering_info ? 0 : sps->max_sub_layers - 1;

    for (i = start; i < sps->max_sub_layers; i++) {

        sps->temporal_layer[i].max_dec_pic_buffering = get_ue_golomb_long(gb) + 1;

        sps->temporal_layer[i].num_reorder_pics      = get_ue_golomb_long(gb);

        sps->temporal_layer[i].max_latency_increase  = get_ue_golomb_long(gb) - 1;

        if (sps->temporal_layer[i].max_dec_pic_buffering > MAX_DPB_SIZE) {

            av_log(s->avctx, AV_LOG_ERROR, "sps_max_dec_pic_buffering_minus1 out of range: %d\n",

                   sps->temporal_layer[i].max_dec_pic_buffering - 1);

            ret = AVERROR_INVALIDDATA;

            goto err;

        }

        if (sps->temporal_layer[i].num_reorder_pics > sps->temporal_layer[i].max_dec_pic_buffering - 1) {

            av_log(s->avctx, AV_LOG_WARNING, "sps_max_num_reorder_pics out of range: %d\n",

                   sps->temporal_layer[i].num_reorder_pics);

            if (s->avctx->err_recognition & AV_EF_EXPLODE ||

                sps->temporal_layer[i].num_reorder_pics > MAX_DPB_SIZE - 1) {

                ret = AVERROR_INVALIDDATA;

                goto err;

            }

            sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[i].num_reorder_pics + 1;

        }

    }

    if (!sublayer_ordering_info) {

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

            sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[start].max_dec_pic_buffering;

            sps->temporal_layer[i].num_reorder_pics      = sps->temporal_layer[start].num_reorder_pics;

            sps->temporal_layer[i].max_latency_increase  = sps->temporal_layer[start].max_latency_increase;

        }

    }

    sps->log2_min_cb_size                    = get_ue_golomb_long(gb) + 3;

    sps->log2_diff_max_min_coding_block_size = get_ue_golomb_long(gb);

    sps->log2_min_tb_size                    = get_ue_golomb_long(gb) + 2;

    log2_diff_max_min_transform_block_size   = get_ue_golomb_long(gb);

    sps->log2_max_trafo_size                 = log2_diff_max_min_transform_block_size +

                                               sps->log2_min_tb_size;

    if (sps->log2_min_tb_size >= sps->log2_min_cb_size) {

        av_log(s->avctx, AV_LOG_ERROR, "Invalid value for log2_min_tb_size");

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    sps->max_transform_hierarchy_depth_inter = get_ue_golomb_long(gb);

    sps->max_transform_hierarchy_depth_intra = get_ue_golomb_long(gb);

    sps->scaling_list_enable_flag = get_bits1(gb);

    if (sps->scaling_list_enable_flag) {

        set_default_scaling_list_data(&sps->scaling_list);

        if (get_bits1(gb)) {

            ret = scaling_list_data(s, &sps->scaling_list, sps);

            if (ret < 0)

                goto err;

        }

    }

    sps->amp_enabled_flag = get_bits1(gb);

    sps->sao_enabled      = get_bits1(gb);

    sps->pcm_enabled_flag = get_bits1(gb);

    if (sps->pcm_enabled_flag) {

        sps->pcm.bit_depth   = get_bits(gb, 4) + 1;

        sps->pcm.bit_depth_chroma = get_bits(gb, 4) + 1;

        sps->pcm.log2_min_pcm_cb_size = get_ue_golomb_long(gb) + 3;

        sps->pcm.log2_max_pcm_cb_size = sps->pcm.log2_min_pcm_cb_size +

                                        get_ue_golomb_long(gb);

        if (sps->pcm.bit_depth > sps->bit_depth) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "PCM bit depth (%d) is greater than normal bit depth (%d)\n",

                   sps->pcm.bit_depth, sps->bit_depth);

            ret = AVERROR_INVALIDDATA;

            goto err;

        }

        sps->pcm.loop_filter_disable_flag = get_bits1(gb);

    }

    sps->nb_st_rps = get_ue_golomb_long(gb);

    if (sps->nb_st_rps > MAX_SHORT_TERM_RPS_COUNT) {

        av_log(s->avctx, AV_LOG_ERROR, "Too many short term RPS: %d.\n",

               sps->nb_st_rps);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    for (i = 0; i < sps->nb_st_rps; i++) {

        if ((ret = ff_hevc_decode_short_term_rps(s, &sps->st_rps[i],

                                                 sps, 0)) < 0)

            goto err;

    }

    sps->long_term_ref_pics_present_flag = get_bits1(gb);

    if (sps->long_term_ref_pics_present_flag) {

        sps->num_long_term_ref_pics_sps = get_ue_golomb_long(gb);

        if (sps->num_long_term_ref_pics_sps > 31U) {

            av_log(s->avctx, AV_LOG_ERROR, "num_long_term_ref_pics_sps %d is out of range.\n",

                   sps->num_long_term_ref_pics_sps);

            goto err;

        }

        for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {

            sps->lt_ref_pic_poc_lsb_sps[i]       = get_bits(gb, sps->log2_max_poc_lsb);

            sps->used_by_curr_pic_lt_sps_flag[i] = get_bits1(gb);

        }

    }

    sps->sps_temporal_mvp_enabled_flag          = get_bits1(gb);

    sps->sps_strong_intra_smoothing_enable_flag = get_bits1(gb);

    sps->vui.sar = (AVRational){0, 1};

    vui_present = get_bits1(gb);

    if (vui_present)

        decode_vui(s, sps);

    if (get_bits1(gb)) { // sps_extension_flag

        int sps_extension_flag[1];

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

            sps_extension_flag[i] = get_bits1(gb);

        skip_bits(gb, 7); //sps_extension_7bits = get_bits(gb, 7);

        if (sps_extension_flag[0]) {

            int extended_precision_processing_flag;

            int high_precision_offsets_enabled_flag;

            int cabac_bypass_alignment_enabled_flag;

            sps->transform_skip_rotation_enabled_flag = get_bits1(gb);

            sps->transform_skip_context_enabled_flag  = get_bits1(gb);

            sps->implicit_rdpcm_enabled_flag = get_bits1(gb);

            sps->explicit_rdpcm_enabled_flag = get_bits1(gb);

            extended_precision_processing_flag = get_bits1(gb);

            if (extended_precision_processing_flag)

                av_log(s->avctx, AV_LOG_WARNING,

                   "extended_precision_processing_flag not yet implemented\n");

            sps->intra_smoothing_disabled_flag       = get_bits1(gb);

            high_precision_offsets_enabled_flag  = get_bits1(gb);

            if (high_precision_offsets_enabled_flag)

                av_log(s->avctx, AV_LOG_WARNING,

                   "high_precision_offsets_enabled_flag not yet implemented\n");

            sps->persistent_rice_adaptation_enabled_flag = get_bits1(gb);

            cabac_bypass_alignment_enabled_flag  = get_bits1(gb);

            if (cabac_bypass_alignment_enabled_flag)

                av_log(s->avctx, AV_LOG_WARNING,

                   "cabac_bypass_alignment_enabled_flag not yet implemented\n");

        }

    }

    if (s->apply_defdispwin) {

        sps->output_window.left_offset   += sps->vui.def_disp_win.left_offset;

        sps->output_window.right_offset  += sps->vui.def_disp_win.right_offset;

        sps->output_window.top_offset    += sps->vui.def_disp_win.top_offset;

        sps->output_window.bottom_offset += sps->vui.def_disp_win.bottom_offset;

    }

    if (sps->output_window.left_offset & (0x1F >> (sps->pixel_shift)) &&

        !(s->avctx->flags & CODEC_FLAG_UNALIGNED)) {

        sps->output_window.left_offset &= ~(0x1F >> (sps->pixel_shift));

        av_log(s->avctx, AV_LOG_WARNING, "Reducing left output window to %d "

               "chroma samples to preserve alignment.\n",

               sps->output_window.left_offset);

    }

    sps->output_width  = sps->width -

                         (sps->output_window.left_offset + sps->output_window.right_offset);

    sps->output_height = sps->height -

                         (sps->output_window.top_offset + sps->output_window.bottom_offset);

    if (sps->output_width <= 0 || sps->output_height <= 0) {

        av_log(s->avctx, AV_LOG_WARNING, "Invalid visible frame dimensions: %dx%d.\n",

               sps->output_width, sps->output_height);

        if (s->avctx->err_recognition & AV_EF_EXPLODE) {

            ret = AVERROR_INVALIDDATA;

            goto err;

        }

        av_log(s->avctx, AV_LOG_WARNING,

               "Displaying the whole video surface.\n");

        memset(&sps->pic_conf_win, 0, sizeof(sps->pic_conf_win));

        memset(&sps->output_window, 0, sizeof(sps->output_window));

        sps->output_width               = sps->width;

        sps->output_height              = sps->height;

    }

    // Inferred parameters

    sps->log2_ctb_size = sps->log2_min_cb_size +

                         sps->log2_diff_max_min_coding_block_size;

    sps->log2_min_pu_size = sps->log2_min_cb_size - 1;

    sps->ctb_width  = (sps->width  + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;

    sps->ctb_height = (sps->height + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;

    sps->ctb_size   = sps->ctb_width * sps->ctb_height;

    sps->min_cb_width  = sps->width  >> sps->log2_min_cb_size;

    sps->min_cb_height = sps->height >> sps->log2_min_cb_size;

    sps->min_tb_width  = sps->width  >> sps->log2_min_tb_size;

    sps->min_tb_height = sps->height >> sps->log2_min_tb_size;

    sps->min_pu_width  = sps->width  >> sps->log2_min_pu_size;

    sps->min_pu_height = sps->height >> sps->log2_min_pu_size;

    sps->tb_mask       = (1 << (sps->log2_ctb_size - sps->log2_min_tb_size)) - 1;

    sps->qp_bd_offset = 6 * (sps->bit_depth - 8);

    if (sps->width  & ((1 << sps->log2_min_cb_size) - 1) ||

        sps->height & ((1 << sps->log2_min_cb_size) - 1)) {

        av_log(s->avctx, AV_LOG_ERROR, "Invalid coded frame dimensions.\n");

        goto err;

    }

    if (sps->log2_ctb_size > MAX_LOG2_CTB_SIZE) {

        av_log(s->avctx, AV_LOG_ERROR, "CTB size out of range: 2^%d\n", sps->log2_ctb_size);

        goto err;

    }

    if (sps->max_transform_hierarchy_depth_inter > sps->log2_ctb_size - sps->log2_min_tb_size) {

        av_log(s->avctx, AV_LOG_ERROR, "max_transform_hierarchy_depth_inter out of range: %d\n",

               sps->max_transform_hierarchy_depth_inter);

        goto err;

    }

    if (sps->max_transform_hierarchy_depth_intra > sps->log2_ctb_size - sps->log2_min_tb_size) {

        av_log(s->avctx, AV_LOG_ERROR, "max_transform_hierarchy_depth_intra out of range: %d\n",

               sps->max_transform_hierarchy_depth_intra);

        goto err;

    }

    if (sps->log2_max_trafo_size > FFMIN(sps->log2_ctb_size, 5)) {

        av_log(s->avctx, AV_LOG_ERROR,

               "max transform block size out of range: %d\n",

               sps->log2_max_trafo_size);

        goto err;

    }

    if (get_bits_left(gb) < 0) {

        av_log(s->avctx, AV_LOG_ERROR,

               "Overread SPS by %d bits\n", -get_bits_left(gb));

        goto err;

    }

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

        av_log(s->avctx, AV_LOG_DEBUG,

               "Parsed SPS: id %d; coded wxh: %dx%d; "

               "cropped wxh: %dx%d; pix_fmt: %s.\n",

               sps_id, sps->width, sps->height,

               sps->output_width, sps->output_height,

               av_get_pix_fmt_name(sps->pix_fmt));

    }

    /* check if this is a repeat of an already parsed SPS, then keep the

     * original one.

     * otherwise drop all PPSes that depend on it */

    if (s->sps_list[sps_id] &&

        !memcmp(s->sps_list[sps_id]->data, sps_buf->data, sps_buf->size)) {

        av_buffer_unref(&sps_buf);

    } else {

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

            if (s->pps_list[i] && ((HEVCPPS*)s->pps_list[i]->data)->sps_id == sps_id)

                av_buffer_unref(&s->pps_list[i]);

        }

        if (s->sps_list[sps_id] && s->sps == (HEVCSPS*)s->sps_list[sps_id]->data) {

            av_buffer_unref(&s->current_sps);

            s->current_sps = av_buffer_ref(s->sps_list[sps_id]);

            if (!s->current_sps)

                s->sps = NULL;

        }

        av_buffer_unref(&s->sps_list[sps_id]);

        s->sps_list[sps_id] = sps_buf;

    }

    return 0;

err:

    av_buffer_unref(&sps_buf);

    return ret;

}


static BlockDriverAIOCB *quorum_aio_readv(BlockDriverState *bs,

                                         int64_t sector_num,

                                         QEMUIOVector *qiov,

                                         int nb_sectors,

                                         BlockDriverCompletionFunc *cb,

                                         void *opaque)

{

    BDRVQuorumState *s = bs->opaque;

    QuorumAIOCB *acb = quorum_aio_get(s, bs, qiov, sector_num,

                                      nb_sectors, cb, opaque);

    int i;

    acb->is_read = true;

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

        acb->qcrs[i].buf = qemu_blockalign(s->bs[i], qiov->size);

        qemu_iovec_init(&acb->qcrs[i].qiov, qiov->niov);

        qemu_iovec_clone(&acb->qcrs[i].qiov, qiov, acb->qcrs[i].buf);

    }

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

        bdrv_aio_readv(s->bs[i], sector_num, &acb->qcrs[i].qiov, nb_sectors,

                       quorum_aio_cb, &acb->qcrs[i]);

    }

    return &acb->common;

}


static int tgv_decode_frame(AVCodecContext *avctx,

                            void *data, int *got_frame,

                            AVPacket *avpkt)

{

    const uint8_t *buf     = avpkt->data;

    int buf_size           = avpkt->size;

    TgvContext *s          = avctx->priv_data;

    const uint8_t *buf_end = buf + buf_size;

    AVFrame *frame         = data;

    int chunk_type, ret;

    if (buf_end - buf < EA_PREAMBLE_SIZE)

        return AVERROR_INVALIDDATA;

    chunk_type = AV_RL32(&buf[0]);

    buf       += EA_PREAMBLE_SIZE;

    if (chunk_type == kVGT_TAG) {

        int pal_count, i;

        if(buf_end - buf < 12) {

            av_log(avctx, AV_LOG_WARNING, "truncated header\n");

            return AVERROR_INVALIDDATA;

        }

        s->width  = AV_RL16(&buf[0]);

        s->height = AV_RL16(&buf[2]);

        if (s->avctx->width != s->width || s->avctx->height != s->height) {

            av_freep(&s->frame_buffer);

            av_frame_unref(s->last_frame);

            if ((ret = ff_set_dimensions(s->avctx, s->width, s->height)) < 0)

                return ret;

        }

        pal_count = AV_RL16(&buf[6]);

        buf += 12;

        for(i = 0; i < pal_count && i < AVPALETTE_COUNT && buf_end - buf >= 3; i++) {

            s->palette[i] = 0xFFU << 24 | AV_RB24(buf);

            buf += 3;

        }

    }

    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)

        return ret;

    memcpy(frame->data[1], s->palette, AVPALETTE_SIZE);

    if (chunk_type == kVGT_TAG) {

        int y;

        frame->key_frame = 1;

        frame->pict_type = AV_PICTURE_TYPE_I;

        if (!s->frame_buffer &&

            !(s->frame_buffer = av_malloc(s->width * s->height)))

            return AVERROR(ENOMEM);

        if (unpack(buf, buf_end, s->frame_buffer, s->avctx->width, s->avctx->height) < 0) {

            av_log(avctx, AV_LOG_WARNING, "truncated intra frame\n");

            return AVERROR_INVALIDDATA;

        }

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

            memcpy(frame->data[0]  + y * frame->linesize[0],

                   s->frame_buffer + y * s->width,

                   s->width);

    } else {

        if (!s->last_frame->data[0]) {

            av_log(avctx, AV_LOG_WARNING, "inter frame without corresponding intra frame\n");

            return buf_size;

        }

        frame->key_frame = 0;

        frame->pict_type = AV_PICTURE_TYPE_P;

        if (tgv_decode_inter(s, frame, buf, buf_end) < 0) {

            av_log(avctx, AV_LOG_WARNING, "truncated inter frame\n");

            return AVERROR_INVALIDDATA;

        }

    }

    av_frame_unref(s->last_frame);

    if ((ret = av_frame_ref(s->last_frame, frame)) < 0)

        return ret;

    *got_frame = 1;

    return buf_size;

}


void HELPER(ove)(CPUOpenRISCState *env, target_ulong test)

{

    if (unlikely(test)) {

        OpenRISCCPU *cpu = openrisc_env_get_cpu(env);

        CPUState *cs = CPU(cpu);

        cs->exception_index = EXCP_RANGE;

        cpu_loop_exit_restore(cs, GETPC());

    }

}


void net_slirp_smb(const char *exported_dir)

{

    struct in_addr vserver_addr = { .s_addr = 0 };

    if (legacy_smb_export) {

        fprintf(stderr, "-smb given twice\n");

        exit(1);

    }

    legacy_smb_export = exported_dir;

    if (!QTAILQ_EMPTY(&slirp_stacks)) {

        slirp_smb(QTAILQ_FIRST(&slirp_stacks), NULL, exported_dir,

                  vserver_addr);

    }

}


static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
                      Error **errp)
{
    BDRVCloopState *s = bs->opaque;
    uint32_t offsets_size, max_compressed_block_size = 1, i;
    int ret;
    bs->read_only = 1;
    /* read header */
    ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
    if (ret < 0) {
        return ret;
    s->block_size = be32_to_cpu(s->block_size);
    ret = bdrv_pread(bs->file, 128 + 4, &s->n_blocks, 4);
    if (ret < 0) {
        return ret;
    s->n_blocks = be32_to_cpu(s->n_blocks);
    /* read offsets */
    offsets_size = s->n_blocks * sizeof(uint64_t);
    s->offsets = g_malloc(offsets_size);
    ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size);
    if (ret < 0) {
        goto fail;
    for(i=0;i<s->n_blocks;i++) {
        s->offsets[i] = be64_to_cpu(s->offsets[i]);
        if (i > 0) {
            uint32_t size = s->offsets[i] - s->offsets[i - 1];
            if (size > max_compressed_block_size) {
                max_compressed_block_size = size;
    /* initialize zlib engine */
    s->compressed_block = g_malloc(max_compressed_block_size + 1);
    s->uncompressed_block = g_malloc(s->block_size);
    if (inflateInit(&s->zstream) != Z_OK) {
        ret = -EINVAL;
        goto fail;
    s->current_block = s->n_blocks;
    s->sectors_per_block = s->block_size/512;
    bs->total_sectors = s->n_blocks * s->sectors_per_block;
    qemu_co_mutex_init(&s->lock);
    return 0;
fail:
    g_free(s->offsets);
    g_free(s->compressed_block);
    g_free(s->uncompressed_block);
    return ret;


void monitor_init(CharDriverState *hd, int show_banner)
{
    int i;
    if (is_first_init) {
        for (i = 0; i < MAX_MON; i++) {
            monitor_hd[i] = NULL;
        }
        is_first_init = 0;
    }
    for (i = 0; i < MAX_MON; i++) {
        if (monitor_hd[i] == NULL) {
            monitor_hd[i] = hd;
            break;
        }
    }
    hide_banner = !show_banner;
    qemu_chr_add_handlers(hd, term_can_read, term_read, term_event, NULL);
}


int ff_h264_decode_slice_header(H264Context *h, H264Context *h0)

{

    unsigned int first_mb_in_slice;

    unsigned int pps_id;

    int ret;

    unsigned int slice_type, tmp, i, j;

    int last_pic_structure, last_pic_droppable;

    int must_reinit;

    int needs_reinit = 0;

    int field_pic_flag, bottom_field_flag;

    int first_slice = h == h0 && !h0->current_slice;

    int frame_num, picture_structure, droppable;

    PPS *pps;

    h->qpel_put = h->h264qpel.put_h264_qpel_pixels_tab;

    h->qpel_avg = h->h264qpel.avg_h264_qpel_pixels_tab;

    first_mb_in_slice = get_ue_golomb_long(&h->gb);

    if (first_mb_in_slice == 0) { // FIXME better field boundary detection

        if (h0->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) {

            ff_h264_field_end(h, 1);

        }

        h0->current_slice = 0;

        if (!h0->first_field) {

            if (h->cur_pic_ptr && !h->droppable) {

                ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,

                                          h->picture_structure == PICT_BOTTOM_FIELD);

            }

            h->cur_pic_ptr = NULL;

        }

    }

    slice_type = get_ue_golomb_31(&h->gb);

    if (slice_type > 9) {

        av_log(h->avctx, AV_LOG_ERROR,

               "slice type %d too large at %d %d\n",

               slice_type, h->mb_x, h->mb_y);

        return AVERROR_INVALIDDATA;

    }

    if (slice_type > 4) {

        slice_type -= 5;

        h->slice_type_fixed = 1;

    } else

        h->slice_type_fixed = 0;

    slice_type = golomb_to_pict_type[slice_type];

    h->slice_type     = slice_type;

    h->slice_type_nos = slice_type & 3;

    if (h->nal_unit_type  == NAL_IDR_SLICE &&

        h->slice_type_nos != AV_PICTURE_TYPE_I) {

        av_log(h->avctx, AV_LOG_ERROR, "A non-intra slice in an IDR NAL unit.\n");

        return AVERROR_INVALIDDATA;

    }

    if (

        (h->avctx->skip_frame >= AVDISCARD_NONREF && !h->nal_ref_idc) ||

        (h->avctx->skip_frame >= AVDISCARD_BIDIR  && h->slice_type_nos == AV_PICTURE_TYPE_B) ||

        (h->avctx->skip_frame >= AVDISCARD_NONINTRA && h->slice_type_nos != AV_PICTURE_TYPE_I) ||

        (h->avctx->skip_frame >= AVDISCARD_NONKEY && h->nal_unit_type != NAL_IDR_SLICE) ||

         h->avctx->skip_frame >= AVDISCARD_ALL) {

         return SLICE_SKIPED;

     }

    // to make a few old functions happy, it's wrong though

    h->pict_type = h->slice_type;

    pps_id = get_ue_golomb(&h->gb);

    if (pps_id >= MAX_PPS_COUNT) {

        av_log(h->avctx, AV_LOG_ERROR, "pps_id %u out of range\n", pps_id);

        return AVERROR_INVALIDDATA;

    }

    if (!h0->pps_buffers[pps_id]) {

        av_log(h->avctx, AV_LOG_ERROR,

               "non-existing PPS %u referenced\n",

               pps_id);

        return AVERROR_INVALIDDATA;

    }

    if (h0->au_pps_id >= 0 && pps_id != h0->au_pps_id) {

        av_log(h->avctx, AV_LOG_ERROR,

               "PPS change from %d to %d forbidden\n",

               h0->au_pps_id, pps_id);

        return AVERROR_INVALIDDATA;

    }

    pps = h0->pps_buffers[pps_id];

    if (!h0->sps_buffers[pps->sps_id]) {

        av_log(h->avctx, AV_LOG_ERROR,

               "non-existing SPS %u referenced\n",

               h->pps.sps_id);

        return AVERROR_INVALIDDATA;

    }

    if (first_slice)

        h->pps = *h0->pps_buffers[pps_id];

    if (pps->sps_id != h->sps.sps_id ||

        pps->sps_id != h->current_sps_id ||

        h0->sps_buffers[pps->sps_id]->new) {

        if (!first_slice) {

            av_log(h->avctx, AV_LOG_ERROR,

               "SPS changed in the middle of the frame\n");

            return AVERROR_INVALIDDATA;

        }

        h->sps = *h0->sps_buffers[h->pps.sps_id];

        if (h->mb_width  != h->sps.mb_width ||

            h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) ||

            h->avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||

            h->cur_chroma_format_idc != h->sps.chroma_format_idc

        )

            needs_reinit = 1;

        if (h->bit_depth_luma    != h->sps.bit_depth_luma ||

            h->chroma_format_idc != h->sps.chroma_format_idc) {

            h->bit_depth_luma    = h->sps.bit_depth_luma;

            h->chroma_format_idc = h->sps.chroma_format_idc;

            needs_reinit         = 1;

        }

        if ((ret = ff_h264_set_parameter_from_sps(h)) < 0)

            return ret;

    }

    h->avctx->profile = ff_h264_get_profile(&h->sps);

    h->avctx->level   = h->sps.level_idc;

    h->avctx->refs    = h->sps.ref_frame_count;

    must_reinit = (h->context_initialized &&

                    (   16*h->sps.mb_width != h->avctx->coded_width

                     || 16*h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) != h->avctx->coded_height

                     || h->avctx->bits_per_raw_sample != h->sps.bit_depth_luma

                     || h->cur_chroma_format_idc != h->sps.chroma_format_idc

                     || h->mb_width  != h->sps.mb_width

                     || h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag)

                    ));

    if (non_j_pixfmt(h0->avctx->pix_fmt) != non_j_pixfmt(get_pixel_format(h0, 0)))

        must_reinit = 1;

    if (first_slice && av_cmp_q(h->sps.sar, h->avctx->sample_aspect_ratio))

        must_reinit = 1;

    h->mb_width  = h->sps.mb_width;

    h->mb_height = h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);

    h->mb_num    = h->mb_width * h->mb_height;

    h->mb_stride = h->mb_width + 1;

    h->b_stride = h->mb_width * 4;

    h->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p

    h->width  = 16 * h->mb_width;

    h->height = 16 * h->mb_height;

    ret = init_dimensions(h);

    if (ret < 0)

        return ret;

    if (h->sps.video_signal_type_present_flag) {

        h->avctx->color_range = h->sps.full_range>0 ? AVCOL_RANGE_JPEG

                                                    : AVCOL_RANGE_MPEG;

        if (h->sps.colour_description_present_flag) {

            if (h->avctx->colorspace != h->sps.colorspace)

                needs_reinit = 1;

            h->avctx->color_primaries = h->sps.color_primaries;

            h->avctx->color_trc       = h->sps.color_trc;

            h->avctx->colorspace      = h->sps.colorspace;

        }

    }

    if (h->context_initialized &&

        (must_reinit || needs_reinit)) {

        if (h != h0) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "changing width %d -> %d / height %d -> %d on "

                   "slice %d\n",

                   h->width, h->avctx->coded_width,

                   h->height, h->avctx->coded_height,

                   h0->current_slice + 1);

            return AVERROR_INVALIDDATA;

        }

        av_assert1(first_slice);

        ff_h264_flush_change(h);

        if ((ret = get_pixel_format(h, 1)) < 0)

            return ret;

        h->avctx->pix_fmt = ret;

        av_log(h->avctx, AV_LOG_INFO, "Reinit context to %dx%d, "

               "pix_fmt: %s\n", h->width, h->height, av_get_pix_fmt_name(h->avctx->pix_fmt));

        if ((ret = h264_slice_header_init(h, 1)) < 0) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "h264_slice_header_init() failed\n");

            return ret;

        }

    }

    if (!h->context_initialized) {

        if (h != h0) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "Cannot (re-)initialize context during parallel decoding.\n");

            return AVERROR_PATCHWELCOME;

        }

        if ((ret = get_pixel_format(h, 1)) < 0)

            return ret;

        h->avctx->pix_fmt = ret;

        if ((ret = h264_slice_header_init(h, 0)) < 0) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "h264_slice_header_init() failed\n");

            return ret;

        }

    }

    if (h == h0 && h->dequant_coeff_pps != pps_id) {

        h->dequant_coeff_pps = pps_id;

        h264_init_dequant_tables(h);

    }

    frame_num = get_bits(&h->gb, h->sps.log2_max_frame_num);

    if (!first_slice) {

        if (h0->frame_num != frame_num) {

            av_log(h->avctx, AV_LOG_ERROR, "Frame num change from %d to %d\n",

                   h0->frame_num, frame_num);

            return AVERROR_INVALIDDATA;

        }

    }

    h->mb_mbaff        = 0;

    h->mb_aff_frame    = 0;

    last_pic_structure = h0->picture_structure;

    last_pic_droppable = h0->droppable;

    droppable          = h->nal_ref_idc == 0;

    if (h->sps.frame_mbs_only_flag) {

        picture_structure = PICT_FRAME;

    } else {

        if (!h->sps.direct_8x8_inference_flag && slice_type == AV_PICTURE_TYPE_B) {

            av_log(h->avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n");

            return -1;

        }

        field_pic_flag = get_bits1(&h->gb);

        if (field_pic_flag) {

            bottom_field_flag = get_bits1(&h->gb);

            picture_structure = PICT_TOP_FIELD + bottom_field_flag;

        } else {

            picture_structure = PICT_FRAME;

            h->mb_aff_frame      = h->sps.mb_aff;

        }

    }

    if (h0->current_slice) {

        if (last_pic_structure != picture_structure ||

            last_pic_droppable != droppable) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "Changing field mode (%d -> %d) between slices is not allowed\n",

                   last_pic_structure, h->picture_structure);

            return AVERROR_INVALIDDATA;

        } else if (!h0->cur_pic_ptr) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "unset cur_pic_ptr on slice %d\n",

                   h0->current_slice + 1);

            return AVERROR_INVALIDDATA;

        }

    }

    h->picture_structure = picture_structure;

    h->droppable         = droppable;

    h->frame_num         = frame_num;

    h->mb_field_decoding_flag = picture_structure != PICT_FRAME;

    if (h0->current_slice == 0) {

        /* Shorten frame num gaps so we don't have to allocate reference

         * frames just to throw them away */

        if (h->frame_num != h->prev_frame_num) {

            int unwrap_prev_frame_num = h->prev_frame_num;

            int max_frame_num         = 1 << h->sps.log2_max_frame_num;

            if (unwrap_prev_frame_num > h->frame_num)

                unwrap_prev_frame_num -= max_frame_num;

            if ((h->frame_num - unwrap_prev_frame_num) > h->sps.ref_frame_count) {

                unwrap_prev_frame_num = (h->frame_num - h->sps.ref_frame_count) - 1;

                if (unwrap_prev_frame_num < 0)

                    unwrap_prev_frame_num += max_frame_num;

                h->prev_frame_num = unwrap_prev_frame_num;

            }

        }

        /* See if we have a decoded first field looking for a pair...

         * Here, we're using that to see if we should mark previously

         * decode frames as "finished".

         * We have to do that before the "dummy" in-between frame allocation,

         * since that can modify h->cur_pic_ptr. */

        if (h0->first_field) {

            assert(h0->cur_pic_ptr);

            assert(h0->cur_pic_ptr->f.buf[0]);

            assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF);

            /* Mark old field/frame as completed */

            if (h0->cur_pic_ptr->tf.owner == h0->avctx) {

                ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,

                                          last_pic_structure == PICT_BOTTOM_FIELD);

            }

            /* figure out if we have a complementary field pair */

            if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) {

                /* Previous field is unmatched. Don't display it, but let it

                 * remain for reference if marked as such. */

                if (last_pic_structure != PICT_FRAME) {

                    ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,

                                              last_pic_structure == PICT_TOP_FIELD);

                }

            } else {

                if (h0->cur_pic_ptr->frame_num != h->frame_num) {

                    /* This and previous field were reference, but had

                     * different frame_nums. Consider this field first in

                     * pair. Throw away previous field except for reference

                     * purposes. */

                    if (last_pic_structure != PICT_FRAME) {

                        ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,

                                                  last_pic_structure == PICT_TOP_FIELD);

                    }

                } else {

                    /* Second field in complementary pair */

                    if (!((last_pic_structure   == PICT_TOP_FIELD &&

                           h->picture_structure == PICT_BOTTOM_FIELD) ||

                          (last_pic_structure   == PICT_BOTTOM_FIELD &&

                           h->picture_structure == PICT_TOP_FIELD))) {

                        av_log(h->avctx, AV_LOG_ERROR,

                               "Invalid field mode combination %d/%d\n",

                               last_pic_structure, h->picture_structure);

                        h->picture_structure = last_pic_structure;

                        h->droppable         = last_pic_droppable;

                        return AVERROR_INVALIDDATA;

                    } else if (last_pic_droppable != h->droppable) {

                        avpriv_request_sample(h->avctx,

                                              "Found reference and non-reference fields in the same frame, which");

                        h->picture_structure = last_pic_structure;

                        h->droppable         = last_pic_droppable;

                        return AVERROR_PATCHWELCOME;

                    }

                }

            }

        }

        while (h->frame_num != h->prev_frame_num && !h0->first_field &&

               h->frame_num != (h->prev_frame_num + 1) % (1 << h->sps.log2_max_frame_num)) {

            H264Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;

            av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",

                   h->frame_num, h->prev_frame_num);

            if (!h->sps.gaps_in_frame_num_allowed_flag)

                for(i=0; i<FF_ARRAY_ELEMS(h->last_pocs); i++)

                    h->last_pocs[i] = INT_MIN;

            ret = h264_frame_start(h);

            if (ret < 0) {

                h0->first_field = 0;

                return ret;

            }

            h->prev_frame_num++;

            h->prev_frame_num        %= 1 << h->sps.log2_max_frame_num;

            h->cur_pic_ptr->frame_num = h->prev_frame_num;

            h->cur_pic_ptr->invalid_gap = !h->sps.gaps_in_frame_num_allowed_flag;

            ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);

            ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);

            ret = ff_generate_sliding_window_mmcos(h, 1);

            if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))

                return ret;

            ret = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);

            if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))

                return ret;

            /* Error concealment: If a ref is missing, copy the previous ref

             * in its place.

             * FIXME: Avoiding a memcpy would be nice, but ref handling makes

             * many assumptions about there being no actual duplicates.

             * FIXME: This does not copy padding for out-of-frame motion

             * vectors.  Given we are concealing a lost frame, this probably

             * is not noticeable by comparison, but it should be fixed. */

            if (h->short_ref_count) {

                if (prev) {

                    av_image_copy(h->short_ref[0]->f.data,

                                  h->short_ref[0]->f.linesize,

                                  (const uint8_t **)prev->f.data,

                                  prev->f.linesize,

                                  h->avctx->pix_fmt,

                                  h->mb_width  * 16,

                                  h->mb_height * 16);

                    h->short_ref[0]->poc = prev->poc + 2;

                }

                h->short_ref[0]->frame_num = h->prev_frame_num;

            }

        }

        /* See if we have a decoded first field looking for a pair...

         * We're using that to see whether to continue decoding in that

         * frame, or to allocate a new one. */

        if (h0->first_field) {

            assert(h0->cur_pic_ptr);

            assert(h0->cur_pic_ptr->f.buf[0]);

            assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF);

            /* figure out if we have a complementary field pair */

            if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) {

                /* Previous field is unmatched. Don't display it, but let it

                 * remain for reference if marked as such. */

                h0->missing_fields ++;

                h0->cur_pic_ptr = NULL;

                h0->first_field = FIELD_PICTURE(h);

            } else {

                h0->missing_fields = 0;

                if (h0->cur_pic_ptr->frame_num != h->frame_num) {

                    ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,

                                              h0->picture_structure==PICT_BOTTOM_FIELD);

                    /* This and the previous field had different frame_nums.

                     * Consider this field first in pair. Throw away previous

                     * one except for reference purposes. */

                    h0->first_field = 1;

                    h0->cur_pic_ptr = NULL;

                } else {

                    /* Second field in complementary pair */

                    h0->first_field = 0;

                }

            }

        } else {

            /* Frame or first field in a potentially complementary pair */

            h0->first_field = FIELD_PICTURE(h);

        }

        if (!FIELD_PICTURE(h) || h0->first_field) {

            if (h264_frame_start(h) < 0) {

                h0->first_field = 0;

                return AVERROR_INVALIDDATA;

            }

        } else {

            release_unused_pictures(h, 0);

        }

        /* Some macroblocks can be accessed before they're available in case

        * of lost slices, MBAFF or threading. */

        if (FIELD_PICTURE(h)) {

            for(i = (h->picture_structure == PICT_BOTTOM_FIELD); i<h->mb_height; i++)

                memset(h->slice_table + i*h->mb_stride, -1, (h->mb_stride - (i+1==h->mb_height)) * sizeof(*h->slice_table));

        } else {

            memset(h->slice_table, -1,

                (h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table));

        }

        h0->last_slice_type = -1;

    }

    if (h != h0 && (ret = clone_slice(h, h0)) < 0)

        return ret;

    /* can't be in alloc_tables because linesize isn't known there.

     * FIXME: redo bipred weight to not require extra buffer? */

    for (i = 0; i < h->slice_context_count; i++)

        if (h->thread_context[i]) {

            ret = alloc_scratch_buffers(h->thread_context[i], h->linesize);

            if (ret < 0)

                return ret;

        }

    h->cur_pic_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup

    av_assert1(h->mb_num == h->mb_width * h->mb_height);

    if (first_mb_in_slice << FIELD_OR_MBAFF_PICTURE(h) >= h->mb_num ||

        first_mb_in_slice >= h->mb_num) {

        av_log(h->avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n");

        return AVERROR_INVALIDDATA;

    }

    h->resync_mb_x = h->mb_x =  first_mb_in_slice % h->mb_width;

    h->resync_mb_y = h->mb_y = (first_mb_in_slice / h->mb_width) <<

                               FIELD_OR_MBAFF_PICTURE(h);

    if (h->picture_structure == PICT_BOTTOM_FIELD)

        h->resync_mb_y = h->mb_y = h->mb_y + 1;

    av_assert1(h->mb_y < h->mb_height);

    if (h->picture_structure == PICT_FRAME) {

        h->curr_pic_num = h->frame_num;

        h->max_pic_num  = 1 << h->sps.log2_max_frame_num;

    } else {

        h->curr_pic_num = 2 * h->frame_num + 1;

        h->max_pic_num  = 1 << (h->sps.log2_max_frame_num + 1);

    }

    if (h->nal_unit_type == NAL_IDR_SLICE)

        get_ue_golomb(&h->gb); /* idr_pic_id */

    if (h->sps.poc_type == 0) {

        h->poc_lsb = get_bits(&h->gb, h->sps.log2_max_poc_lsb);

        if (h->pps.pic_order_present == 1 && h->picture_structure == PICT_FRAME)

            h->delta_poc_bottom = get_se_golomb(&h->gb);

    }

    if (h->sps.poc_type == 1 && !h->sps.delta_pic_order_always_zero_flag) {

        h->delta_poc[0] = get_se_golomb(&h->gb);

        if (h->pps.pic_order_present == 1 && h->picture_structure == PICT_FRAME)

            h->delta_poc[1] = get_se_golomb(&h->gb);

    }

    ff_init_poc(h, h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc);

    if (h->pps.redundant_pic_cnt_present)

        h->redundant_pic_count = get_ue_golomb(&h->gb);

    ret = ff_set_ref_count(h);

    if (ret < 0)

        return ret;

    if (slice_type != AV_PICTURE_TYPE_I &&

        (h0->current_slice == 0 ||

         slice_type != h0->last_slice_type ||

         memcmp(h0->last_ref_count, h0->ref_count, sizeof(h0->ref_count)))) {

        ff_h264_fill_default_ref_list(h);

    }

    if (h->slice_type_nos != AV_PICTURE_TYPE_I) {

       ret = ff_h264_decode_ref_pic_list_reordering(h);

       if (ret < 0) {

           h->ref_count[1] = h->ref_count[0] = 0;

           return ret;

       }

    }

    if ((h->pps.weighted_pred && h->slice_type_nos == AV_PICTURE_TYPE_P) ||

        (h->pps.weighted_bipred_idc == 1 &&

         h->slice_type_nos == AV_PICTURE_TYPE_B))

        ff_pred_weight_table(h);

    else if (h->pps.weighted_bipred_idc == 2 &&

             h->slice_type_nos == AV_PICTURE_TYPE_B) {

        implicit_weight_table(h, -1);

    } else {

        h->use_weight = 0;

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

            h->luma_weight_flag[i]   = 0;

            h->chroma_weight_flag[i] = 0;

        }

    }

    // If frame-mt is enabled, only update mmco tables for the first slice

    // in a field. Subsequent slices can temporarily clobber h->mmco_index

    // or h->mmco, which will cause ref list mix-ups and decoding errors

    // further down the line. This may break decoding if the first slice is

    // corrupt, thus we only do this if frame-mt is enabled.

    if (h->nal_ref_idc) {

        ret = ff_h264_decode_ref_pic_marking(h0, &h->gb,

                                             !(h->avctx->active_thread_type & FF_THREAD_FRAME) ||

                                             h0->current_slice == 0);

        if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))

            return AVERROR_INVALIDDATA;

    }

    if (FRAME_MBAFF(h)) {

        ff_h264_fill_mbaff_ref_list(h);

        if (h->pps.weighted_bipred_idc == 2 && h->slice_type_nos == AV_PICTURE_TYPE_B) {

            implicit_weight_table(h, 0);

            implicit_weight_table(h, 1);

        }

    }

    if (h->slice_type_nos == AV_PICTURE_TYPE_B && !h->direct_spatial_mv_pred)

        ff_h264_direct_dist_scale_factor(h);

    ff_h264_direct_ref_list_init(h);

    if (h->slice_type_nos != AV_PICTURE_TYPE_I && h->pps.cabac) {

        tmp = get_ue_golomb_31(&h->gb);

        if (tmp > 2) {

            av_log(h->avctx, AV_LOG_ERROR, "cabac_init_idc %u overflow\n", tmp);

            return AVERROR_INVALIDDATA;

        }

        h->cabac_init_idc = tmp;

    }

    h->last_qscale_diff = 0;

    tmp = h->pps.init_qp + get_se_golomb(&h->gb);

    if (tmp > 51 + 6 * (h->sps.bit_depth_luma - 8)) {

        av_log(h->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);

        return AVERROR_INVALIDDATA;

    }

    h->qscale       = tmp;

    h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);

    h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);

    // FIXME qscale / qp ... stuff

    if (h->slice_type == AV_PICTURE_TYPE_SP)

        get_bits1(&h->gb); /* sp_for_switch_flag */

    if (h->slice_type == AV_PICTURE_TYPE_SP ||

        h->slice_type == AV_PICTURE_TYPE_SI)

        get_se_golomb(&h->gb); /* slice_qs_delta */

    h->deblocking_filter     = 1;

    h->slice_alpha_c0_offset = 0;

    h->slice_beta_offset     = 0;

    if (h->pps.deblocking_filter_parameters_present) {

        tmp = get_ue_golomb_31(&h->gb);

        if (tmp > 2) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "deblocking_filter_idc %u out of range\n", tmp);

            return AVERROR_INVALIDDATA;

        }

        h->deblocking_filter = tmp;

        if (h->deblocking_filter < 2)

            h->deblocking_filter ^= 1;  // 1<->0

        if (h->deblocking_filter) {

            h->slice_alpha_c0_offset = get_se_golomb(&h->gb) * 2;

            h->slice_beta_offset     = get_se_golomb(&h->gb) * 2;

            if (h->slice_alpha_c0_offset >  12 ||

                h->slice_alpha_c0_offset < -12 ||

                h->slice_beta_offset >  12     ||

                h->slice_beta_offset < -12) {

                av_log(h->avctx, AV_LOG_ERROR,

                       "deblocking filter parameters %d %d out of range\n",

                       h->slice_alpha_c0_offset, h->slice_beta_offset);

                return AVERROR_INVALIDDATA;

            }

        }

    }

    if (h->avctx->skip_loop_filter >= AVDISCARD_ALL ||

        (h->avctx->skip_loop_filter >= AVDISCARD_NONKEY &&

         h->nal_unit_type != NAL_IDR_SLICE) ||

        (h->avctx->skip_loop_filter >= AVDISCARD_NONINTRA &&

         h->slice_type_nos != AV_PICTURE_TYPE_I) ||

        (h->avctx->skip_loop_filter >= AVDISCARD_BIDIR  &&

         h->slice_type_nos == AV_PICTURE_TYPE_B) ||

        (h->avctx->skip_loop_filter >= AVDISCARD_NONREF &&

         h->nal_ref_idc == 0))

        h->deblocking_filter = 0;

    if (h->deblocking_filter == 1 && h0->max_contexts > 1) {

        if (h->avctx->flags2 & CODEC_FLAG2_FAST) {

            /* Cheat slightly for speed:

             * Do not bother to deblock across slices. */

            h->deblocking_filter = 2;

        } else {

            h0->max_contexts = 1;

            if (!h0->single_decode_warning) {

                av_log(h->avctx, AV_LOG_INFO,

                       "Cannot parallelize slice decoding with deblocking filter type 1, decoding such frames in sequential order\n"

                       "To parallelize slice decoding you need video encoded with disable_deblocking_filter_idc set to 2 (deblock only edges that do not cross slices).\n"

                       "Setting the flags2 libavcodec option to +fast (-flags2 +fast) will disable deblocking across slices and enable parallel slice decoding "

                       "but will generate non-standard-compliant output.\n");

                h0->single_decode_warning = 1;

            }

            if (h != h0) {

                av_log(h->avctx, AV_LOG_ERROR,

                       "Deblocking switched inside frame.\n");

                return SLICE_SINGLETHREAD;

            }

        }

    }

    h->qp_thresh = 15 -

                   FFMIN(h->slice_alpha_c0_offset, h->slice_beta_offset) -

                   FFMAX3(0,

                          h->pps.chroma_qp_index_offset[0],

                          h->pps.chroma_qp_index_offset[1]) +

                   6 * (h->sps.bit_depth_luma - 8);

    h0->last_slice_type = slice_type;

    memcpy(h0->last_ref_count, h0->ref_count, sizeof(h0->last_ref_count));

    h->slice_num        = ++h0->current_slice;

    if (h->slice_num)

        h0->slice_row[(h->slice_num-1)&(MAX_SLICES-1)]= h->resync_mb_y;

    if (   h0->slice_row[h->slice_num&(MAX_SLICES-1)] + 3 >= h->resync_mb_y

        && h0->slice_row[h->slice_num&(MAX_SLICES-1)] <= h->resync_mb_y

        && h->slice_num >= MAX_SLICES) {

        //in case of ASO this check needs to be updated depending on how we decide to assign slice numbers in this case

        av_log(h->avctx, AV_LOG_WARNING, "Possibly too many slices (%d >= %d), increase MAX_SLICES and recompile if there are artifacts\n", h->slice_num, MAX_SLICES);

    }

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

        int id_list[16];

        int *ref2frm = h->ref2frm[h->slice_num & (MAX_SLICES - 1)][j];

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

            id_list[i] = 60;

            if (j < h->list_count && i < h->ref_count[j] &&

                h->ref_list[j][i].f.buf[0]) {

                int k;

                AVBuffer *buf = h->ref_list[j][i].f.buf[0]->buffer;

                for (k = 0; k < h->short_ref_count; k++)

                    if (h->short_ref[k]->f.buf[0]->buffer == buf) {

                        id_list[i] = k;

                        break;

                    }

                for (k = 0; k < h->long_ref_count; k++)

                    if (h->long_ref[k] && h->long_ref[k]->f.buf[0]->buffer == buf) {

                        id_list[i] = h->short_ref_count + k;

                        break;

                    }

            }

        }

        ref2frm[0] =

        ref2frm[1] = -1;

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

            ref2frm[i + 2] = 4 * id_list[i] + (h->ref_list[j][i].reference & 3);

        ref2frm[18 + 0] =

        ref2frm[18 + 1] = -1;

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

            ref2frm[i + 4] = 4 * id_list[(i - 16) >> 1] +

                             (h->ref_list[j][i].reference & 3);

    }

    h0->au_pps_id = pps_id;

    h->sps.new =

    h0->sps_buffers[h->pps.sps_id]->new = 0;

    h->current_sps_id = h->pps.sps_id;

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

        av_log(h->avctx, AV_LOG_DEBUG,

               "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n",

               h->slice_num,

               (h->picture_structure == PICT_FRAME ? "F" : h->picture_structure == PICT_TOP_FIELD ? "T" : "B"),

               first_mb_in_slice,

               av_get_picture_type_char(h->slice_type),

               h->slice_type_fixed ? " fix" : "",

               h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "",

               pps_id, h->frame_num,

               h->cur_pic_ptr->field_poc[0],

               h->cur_pic_ptr->field_poc[1],

               h->ref_count[0], h->ref_count[1],

               h->qscale,

               h->deblocking_filter,

               h->slice_alpha_c0_offset, h->slice_beta_offset,

               h->use_weight,

               h->use_weight == 1 && h->use_weight_chroma ? "c" : "",

               h->slice_type == AV_PICTURE_TYPE_B ? (h->direct_spatial_mv_pred ? "SPAT" : "TEMP") : "");

    }

    return 0;

}


static void spatial_compose53i_dy_buffered(dwt_compose_t *cs, slice_buffer * sb, int width, int height, int stride_line){

    int y= cs->y;

    int mirror0 = mirror(y-1, height-1);

    int mirror1 = mirror(y  , height-1);

    int mirror2 = mirror(y+1, height-1);

    int mirror3 = mirror(y+2, height-1);

    DWTELEM *b0= cs->b0;

    DWTELEM *b1= cs->b1;

    DWTELEM *b2= slice_buffer_get_line(sb, mirror2 * stride_line);

    DWTELEM *b3= slice_buffer_get_line(sb, mirror3 * stride_line);

{START_TIMER

        if(mirror1 <= mirror3) vertical_compose53iL0(b1, b2, b3, width);

        if(mirror0 <= mirror2) vertical_compose53iH0(b0, b1, b2, width);

STOP_TIMER("vertical_compose53i*")}

{START_TIMER

        if(y-1 >= 0) horizontal_compose53i(b0, width);

        if(mirror0 <= mirror2) horizontal_compose53i(b1, width);

STOP_TIMER("horizontal_compose53i")}

    cs->b0 = b2;

    cs->b1 = b3;

    cs->y += 2;

}