vcard_emul_login(VCard *card, unsigned char *pin, int pin_len)

{

    PK11SlotInfo *slot;

    unsigned char *pin_string = NULL;

    int i;

    SECStatus rv;

    if (!nss_emul_init) {

        return VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED;

    }

    slot = vcard_emul_card_get_slot(card);

     /* We depend on the PKCS #11 module internal login state here because we

      * create a separate process to handle each guest instance. If we needed

      * to handle multiple guests from one process, then we would need to keep

      * a lot of extra state in our card structure

      * */

    pin_string = g_malloc(pin_len+1);

    memcpy(pin_string, pin, pin_len);

    pin_string[pin_len] = 0;

    /* handle CAC expanded pins correctly */

    for (i = pin_len-1; i >= 0 && (pin_string[i] == 0xff); i--) {

        pin_string[i] = 0;

    }

    rv = PK11_Authenticate(slot, PR_FALSE, pin_string);

    memset(pin_string, 0, pin_len);  /* don't let the pin hang around in memory

                                        to be snooped */

    g_free(pin_string);

    if (rv == SECSuccess) {

        return VCARD7816_STATUS_SUCCESS;

    }

    /* map the error from port get error */

    return VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED;

}


static int motion_inter_block (bit_buffer_t *bitbuf,

			       uint8_t *current, uint8_t *previous, int pitch,

			       svq1_pmv_t *motion, int x, int y) {

  uint8_t    *src;

  uint8_t    *dst;

  svq1_pmv_t  mv;

  svq1_pmv_t *pmv[3];

  int	      result;

  /* predict and decode motion vector */

  pmv[0] = &motion[0];

  pmv[1] = &motion[(x / 8) + 2];

  pmv[2] = &motion[(x / 8) + 4];

  if (y == 0) {

    pmv[1] = pmv[0];

    pmv[2] = pmv[0];

  }

  result = decode_motion_vector (bitbuf, &mv, pmv);

  if (result != 0)

    return result;

  motion[0].x		= mv.x;

  motion[0].y		= mv.y;

  motion[(x / 8) + 2].x	= mv.x;

  motion[(x / 8) + 2].y	= mv.y;

  motion[(x / 8) + 3].x	= mv.x;

  motion[(x / 8) + 3].y	= mv.y;

  src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1))*pitch];

  dst = current;

  put_pixels_tab[((mv.y & 1) << 1) | (mv.x & 1)](dst,src,pitch,16);

  put_pixels_tab[((mv.y & 1) << 1) | (mv.x & 1)](dst+8,src+8,pitch,16);

  return 0;

}


vreader_list_delete(VReaderList *list)

{

    VReaderListEntry *current_entry;

    VReaderListEntry *next_entry = NULL;

    for (current_entry = vreader_list_get_first(list); current_entry;

         current_entry = next_entry) {

        next_entry = vreader_list_get_next(current_entry);

        vreader_list_entry_delete(current_entry);

    }

    list->head = NULL;

    list->tail = NULL;

    g_free(list);

}


static uint32_t cadence_ttc_read_imp(void *opaque, target_phys_addr_t offset)

{

    CadenceTimerState *s = cadence_timer_from_addr(opaque, offset);

    uint32_t value;

    cadence_timer_sync(s);

    cadence_timer_run(s);

    switch (offset) {

    case 0x00: /* clock control */

    case 0x04:

    case 0x08:

        return s->reg_clock;

    case 0x0c: /* counter control */

    case 0x10:

    case 0x14:

        return s->reg_count;

    case 0x18: /* counter value */

    case 0x1c:

    case 0x20:

        return (uint16_t)(s->reg_value >> 16);

    case 0x24: /* reg_interval counter */

    case 0x28:

    case 0x2c:

        return s->reg_interval;

    case 0x30: /* match 1 counter */

    case 0x34:

    case 0x38:

        return s->reg_match[0];

    case 0x3c: /* match 2 counter */

    case 0x40:

    case 0x44:

        return s->reg_match[1];

    case 0x48: /* match 3 counter */

    case 0x4c:

    case 0x50:

        return s->reg_match[2];

    case 0x54: /* interrupt register */

    case 0x58:

    case 0x5c:

        /* cleared after read */

        value = s->reg_intr;

        s->reg_intr = 0;

        cadence_timer_update(s);

        return value;

    case 0x60: /* interrupt enable */

    case 0x64:

    case 0x68:

        return s->reg_intr_en;

    case 0x6c:

    case 0x70:

    case 0x74:

        return s->reg_event_ctrl;

    case 0x78:

    case 0x7c:

    case 0x80:

        return s->reg_event;

    default:

        return 0;

    }

}


static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,

    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov,

    BdrvRequestFlags flags)

{

    if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {

        return -EINVAL;

    }

    return bdrv_co_do_pwritev(bs, sector_num << BDRV_SECTOR_BITS,

                              nb_sectors << BDRV_SECTOR_BITS, qiov, flags);

}


static int vnc_display_connect(VncDisplay *vd,

                               SocketAddress **saddr,

                               size_t nsaddr,

                               SocketAddress **wsaddr,

                               size_t nwsaddr,

                               Error **errp)

{

    /* connect to viewer */

    QIOChannelSocket *sioc = NULL;

    if (nwsaddr != 0) {

        error_setg(errp, "Cannot use websockets in reverse mode");

        return -1;

    }

    if (nsaddr != 1) {

        error_setg(errp, "Expected a single address in reverse mode");

        return -1;

    }

    /* TODO SOCKET_ADDRESS_KIND_FD when fd has AF_UNIX */

    vd->is_unix = saddr[0]->type == SOCKET_ADDRESS_KIND_UNIX;

    sioc = qio_channel_socket_new();

    qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");

    if (qio_channel_socket_connect_sync(sioc, saddr[0], errp) < 0) {

        return -1;

    }

    vnc_connect(vd, sioc, false, false);

    object_unref(OBJECT(sioc));

    return 0;

}


static int vfio_add_ext_cap(VFIOPCIDevice *vdev)

{

    PCIDevice *pdev = &vdev->pdev;

    uint32_t header;

    uint16_t cap_id, next, size;

    uint8_t cap_ver;

    uint8_t *config;

    /*

     * pcie_add_capability always inserts the new capability at the tail

     * of the chain.  Therefore to end up with a chain that matches the

     * physical device, we cache the config space to avoid overwriting

     * the original config space when we parse the extended capabilities.

     */

    config = g_memdup(pdev->config, vdev->config_size);

    for (next = PCI_CONFIG_SPACE_SIZE; next;

         next = PCI_EXT_CAP_NEXT(pci_get_long(config + next))) {

        header = pci_get_long(config + next);

        cap_id = PCI_EXT_CAP_ID(header);

        cap_ver = PCI_EXT_CAP_VER(header);

        /*

         * If it becomes important to configure extended capabilities to their

         * actual size, use this as the default when it's something we don't

         * recognize. Since QEMU doesn't actually handle many of the config

         * accesses, exact size doesn't seem worthwhile.

         */

        size = vfio_ext_cap_max_size(config, next);

        pcie_add_capability(pdev, cap_id, cap_ver, next, size);

        pci_set_long(pdev->config + next, PCI_EXT_CAP(cap_id, cap_ver, 0));

        /* Use emulated next pointer to allow dropping extended caps */

        pci_long_test_and_set_mask(vdev->emulated_config_bits + next,

                                   PCI_EXT_CAP_NEXT_MASK);

    }

    g_free(config);

    return 0;

}


void desc_ring_free(DescRing *ring)

{

    if (ring->info) {

        g_free(ring->info);

    }

    g_free(ring);

}


setup_return(CPUState *env, struct emulated_sigaction *ka,

	     abi_ulong *rc, void *frame, int usig)

{

	abi_ulong handler = (abi_ulong)ka->sa._sa_handler;

	abi_ulong retcode;

	int thumb = 0;

#if defined(TARGET_CONFIG_CPU_32)

#if 0

	abi_ulong cpsr = env->cpsr;

	/*

	 * Maybe we need to deliver a 32-bit signal to a 26-bit task.

	 */

	if (ka->sa.sa_flags & SA_THIRTYTWO)

		cpsr = (cpsr & ~MODE_MASK) | USR_MODE;

#ifdef CONFIG_ARM_THUMB

	if (elf_hwcap & HWCAP_THUMB) {

		/*

		 * The LSB of the handler determines if we're going to

		 * be using THUMB or ARM mode for this signal handler.

		 */

		thumb = handler & 1;

		if (thumb)

			cpsr |= T_BIT;

		else

			cpsr &= ~T_BIT;

	}

#endif /* CONFIG_ARM_THUMB */

#endif /* 0 */

#endif /* TARGET_CONFIG_CPU_32 */

	if (ka->sa.sa_flags & TARGET_SA_RESTORER) {

		retcode = (abi_ulong)ka->sa.sa_restorer;

	} else {

		unsigned int idx = thumb;

		if (ka->sa.sa_flags & TARGET_SA_SIGINFO)

			idx += 2;

		if (__put_user(retcodes[idx], rc))

			return 1;

#if 0

		flush_icache_range((abi_ulong)rc,

				   (abi_ulong)(rc + 1));

#endif

		retcode = ((abi_ulong)rc) + thumb;

	}

	env->regs[0] = usig;

	env->regs[13] = h2g(frame);

	env->regs[14] = retcode;

	env->regs[15] = handler & (thumb ? ~1 : ~3);

#if 0

#ifdef TARGET_CONFIG_CPU_32

	env->cpsr = cpsr;

#endif

#endif

	return 0;

}


BlockStatsList *qmp_query_blockstats(bool has_query_nodes,

                                     bool query_nodes,

                                     Error **errp)

{

    BlockStatsList *head = NULL, **p_next = &head;

    BlockBackend *blk = NULL;

    BlockDriverState *bs = NULL;

    /* Just to be safe if query_nodes is not always initialized */

    query_nodes = has_query_nodes && query_nodes;

    while (next_query_bds(&blk, &bs, query_nodes)) {

        BlockStatsList *info = g_malloc0(sizeof(*info));

        AioContext *ctx = blk ? blk_get_aio_context(blk)

                              : bdrv_get_aio_context(bs);

        aio_context_acquire(ctx);

        info->value = bdrv_query_stats(blk, bs, !query_nodes);

        aio_context_release(ctx);

        *p_next = info;

        p_next = &info->next;

    }

    return head;

}


static void dp8393x_writel(void *opaque, target_phys_addr_t addr, uint32_t val)

{

    dp8393x_writew(opaque, addr, val & 0xffff);

    dp8393x_writew(opaque, addr + 2, (val >> 16) & 0xffff);

}


void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,

                       usb_attachfn attach)

{

    port->opaque = opaque;

    port->index = index;

    port->attach = attach;

    TAILQ_INSERT_TAIL(&bus->free, port, next);

    bus->nfree++;

}


static void scsi_read_data(SCSIRequest *req)

{

    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);

    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);

    bool first;

    DPRINTF("Read sector_count=%d\n", r->sector_count);

    if (r->sector_count == 0) {

        /* This also clears the sense buffer for REQUEST SENSE.  */

        scsi_req_complete(&r->req, GOOD);

        return;

    }

    /* No data transfer may already be in progress */

    assert(r->req.aiocb == NULL);

    /* The request is used as the AIO opaque value, so add a ref.  */

    scsi_req_ref(&r->req);

    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {

        DPRINTF("Data transfer direction invalid\n");

        scsi_read_complete(r, -EINVAL);

        return;

    }

    if (s->tray_open) {

        scsi_read_complete(r, -ENOMEDIUM);

        return;

    }

    first = !r->started;

    r->started = true;

    if (first && r->need_fua_emulation) {

        block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0,

                         BLOCK_ACCT_FLUSH);

        r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_do_read_cb, r);

    } else {

        scsi_do_read(r, 0);

    }

}


void qmp_cont(Error **errp)

{

    Error *local_err = NULL;

    BlockBackend *blk;

    BlockDriverState *bs;

    BdrvNextIterator it;

    /* if there is a dump in background, we should wait until the dump

     * finished */

    if (dump_in_progress()) {

        error_setg(errp, "There is a dump in process, please wait.");

        return;

    }

    if (runstate_needs_reset()) {

        error_setg(errp, "Resetting the Virtual Machine is required");

        return;

    } else if (runstate_check(RUN_STATE_SUSPENDED)) {

        return;

    }

    for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {

        blk_iostatus_reset(blk);

    }

    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {

        bdrv_add_key(bs, NULL, &local_err);

        if (local_err) {

            error_propagate(errp, local_err);

            return;

        }

    }

    /* Continuing after completed migration. Images have been inactivated to

     * allow the destination to take control. Need to get control back now.

     *

     * If there are no inactive block nodes (e.g. because the VM was just

     * paused rather than completing a migration), bdrv_inactivate_all() simply

     * doesn't do anything. */

    bdrv_invalidate_cache_all(&local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        return;

    }

    blk_resume_after_migration(&local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        return;

    }

    if (runstate_check(RUN_STATE_INMIGRATE)) {

        autostart = 1;

    } else {

        vm_start();

    }

}


static void ehci_queues_rip_unused(EHCIState *ehci, int async, int flush)

{

    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;

    uint64_t maxage = FRAME_TIMER_NS * ehci->maxframes * 4;

    EHCIQueue *q, *tmp;

    QTAILQ_FOREACH_SAFE(q, head, next, tmp) {

        if (q->seen) {

            q->seen = 0;

            q->ts = ehci->last_run_ns;

            continue;

        }

        if (!flush && ehci->last_run_ns < q->ts + maxage) {

            continue;

        }

        ehci_free_queue(q);

    }

}


static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)

{

    struct mipid_s *s = (struct mipid_s *) opaque;

    uint8_t ret;

    if (len > 9) {

        hw_error("%s: FIXME: bad SPI word width %i\n", __FUNCTION__, len);

    }

    if (s->p >= ARRAY_SIZE(s->resp)) {

        ret = 0;

    } else {

        ret = s->resp[s->p++];

    }

    if (s->pm-- > 0) {

        s->param[s->pm] = cmd;

    } else {

        s->cmd = cmd;

    }

    switch (s->cmd) {

    case 0x00:	/* NOP */

        break;

    case 0x01:	/* SWRESET */

        mipid_reset(s);

        break;

    case 0x02:	/* BSTROFF */

        s->booster = 0;

        break;

    case 0x03:	/* BSTRON */

        s->booster = 1;

        break;

    case 0x04:	/* RDDID */

        s->p = 0;

        s->resp[0] = (s->id >> 16) & 0xff;

        s->resp[1] = (s->id >>  8) & 0xff;

        s->resp[2] = (s->id >>  0) & 0xff;

        break;

    case 0x06:	/* RD_RED */

    case 0x07:	/* RD_GREEN */

        /* XXX the bootloader sometimes issues RD_BLUE meaning RDDID so

         * for the bootloader one needs to change this.  */

    case 0x08:	/* RD_BLUE */

        s->p = 0;

        /* TODO: return first pixel components */

        s->resp[0] = 0x01;

        break;

    case 0x09:	/* RDDST */

        s->p = 0;

        s->resp[0] = s->booster << 7;

        s->resp[1] = (5 << 4) | (s->partial << 2) |

                (s->sleep << 1) | s->normal;

        s->resp[2] = (s->vscr << 7) | (s->invert << 5) |

                (s->onoff << 2) | (s->te << 1) | (s->gamma >> 2);

        s->resp[3] = s->gamma << 6;

        break;

    case 0x0a:	/* RDDPM */

        s->p = 0;

        s->resp[0] = (s->onoff << 2) | (s->normal << 3) | (s->sleep << 4) |

                (s->partial << 5) | (s->sleep << 6) | (s->booster << 7);

        break;

    case 0x0b:	/* RDDMADCTR */

        s->p = 0;

        s->resp[0] = 0;

        break;

    case 0x0c:	/* RDDCOLMOD */

        s->p = 0;

        s->resp[0] = 5;	/* 65K colours */

        break;

    case 0x0d:	/* RDDIM */

        s->p = 0;

        s->resp[0] = (s->invert << 5) | (s->vscr << 7) | s->gamma;

        break;

    case 0x0e:	/* RDDSM */

        s->p = 0;

        s->resp[0] = s->te << 7;

        break;

    case 0x0f:	/* RDDSDR */

        s->p = 0;

        s->resp[0] = s->selfcheck;

        break;

    case 0x10:	/* SLPIN */

        s->sleep = 1;

        break;

    case 0x11:	/* SLPOUT */

        s->sleep = 0;

        s->selfcheck ^= 1 << 6;	/* POFF self-diagnosis Ok */

        break;

    case 0x12:	/* PTLON */

        s->partial = 1;

        s->normal = 0;

        s->vscr = 0;

        break;

    case 0x13:	/* NORON */

        s->partial = 0;

        s->normal = 1;

        s->vscr = 0;

        break;

    case 0x20:	/* INVOFF */

        s->invert = 0;

        break;

    case 0x21:	/* INVON */

        s->invert = 1;

        break;

    case 0x22:	/* APOFF */

    case 0x23:	/* APON */

        goto bad_cmd;

    case 0x25:	/* WRCNTR */

        if (s->pm < 0) {

            s->pm = 1;

        }

        goto bad_cmd;

    case 0x26:	/* GAMSET */

        if (!s->pm) {

            s->gamma = ctz32(s->param[0] & 0xf);

            if (s->gamma == 32) {

                s->gamma = -1; /* XXX: should this be 0? */

            }

        } else if (s->pm < 0) {

            s->pm = 1;

        }

        break;

    case 0x28:	/* DISPOFF */

        s->onoff = 0;

        break;

    case 0x29:	/* DISPON */

        s->onoff = 1;

        break;

    case 0x2a:	/* CASET */

    case 0x2b:	/* RASET */

    case 0x2c:	/* RAMWR */

    case 0x2d:	/* RGBSET */

    case 0x2e:	/* RAMRD */

    case 0x30:	/* PTLAR */

    case 0x33:	/* SCRLAR */

        goto bad_cmd;

    case 0x34:	/* TEOFF */

        s->te = 0;

        break;

    case 0x35:	/* TEON */

        if (!s->pm) {

            s->te = 1;

        } else if (s->pm < 0) {

            s->pm = 1;

        }

        break;

    case 0x36:	/* MADCTR */

        goto bad_cmd;

    case 0x37:	/* VSCSAD */

        s->partial = 0;

        s->normal = 0;

        s->vscr = 1;

        break;

    case 0x38:	/* IDMOFF */

    case 0x39:	/* IDMON */

    case 0x3a:	/* COLMOD */

        goto bad_cmd;

    case 0xb0:	/* CLKINT / DISCTL */

    case 0xb1:	/* CLKEXT */

        if (s->pm < 0) {

            s->pm = 2;

        }

        break;

    case 0xb4:	/* FRMSEL */

        break;

    case 0xb5:	/* FRM8SEL */

    case 0xb6:	/* TMPRNG / INIESC */

    case 0xb7:	/* TMPHIS / NOP2 */

    case 0xb8:	/* TMPREAD / MADCTL */

    case 0xba:	/* DISTCTR */

    case 0xbb:	/* EPVOL */

        goto bad_cmd;

    case 0xbd:	/* Unknown */

        s->p = 0;

        s->resp[0] = 0;

        s->resp[1] = 1;

        break;

    case 0xc2:	/* IFMOD */

        if (s->pm < 0) {

            s->pm = 2;

        }

        break;

    case 0xc6:	/* PWRCTL */

    case 0xc7:	/* PPWRCTL */

    case 0xd0:	/* EPWROUT */

    case 0xd1:	/* EPWRIN */

    case 0xd4:	/* RDEV */

    case 0xd5:	/* RDRR */

        goto bad_cmd;

    case 0xda:	/* RDID1 */

        s->p = 0;

        s->resp[0] = (s->id >> 16) & 0xff;

        break;

    case 0xdb:	/* RDID2 */

        s->p = 0;

        s->resp[0] = (s->id >>  8) & 0xff;

        break;

    case 0xdc:	/* RDID3 */

        s->p = 0;

        s->resp[0] = (s->id >>  0) & 0xff;

        break;

    default:

    bad_cmd:

        qemu_log_mask(LOG_GUEST_ERROR,

                      "%s: unknown command %02x\n", __func__, s->cmd);

        break;

    }

    return ret;

}


static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)

{

    int i;

    unsigned int enc = 0;

    vnc_zlib_init(vs);

    vs->features = 0;

    vs->vnc_encoding = -1;

    vs->tight_compression = 9;

    vs->tight_quality = 9;

    vs->absolute = -1;

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

        enc = encodings[i];

        switch (enc) {

        case VNC_ENCODING_RAW:

            if (vs->vnc_encoding != -1) {

                vs->vnc_encoding = enc;

            }

            break;

        case VNC_ENCODING_COPYRECT:

            vs->features |= VNC_FEATURE_COPYRECT_MASK;

            break;

        case VNC_ENCODING_HEXTILE:

            vs->features |= VNC_FEATURE_HEXTILE_MASK;

            if (vs->vnc_encoding != -1) {

                vs->vnc_encoding = enc;

            }

            break;

        case VNC_ENCODING_ZLIB:

            vs->features |= VNC_FEATURE_ZLIB_MASK;

            if (vs->vnc_encoding != -1) {

                vs->vnc_encoding = enc;

            }

            break;

        case VNC_ENCODING_DESKTOPRESIZE:

            vs->features |= VNC_FEATURE_RESIZE_MASK;

            break;

        case VNC_ENCODING_POINTER_TYPE_CHANGE:

            vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;

            break;

        case VNC_ENCODING_RICH_CURSOR:

            vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;

            break;

        case VNC_ENCODING_EXT_KEY_EVENT:

            send_ext_key_event_ack(vs);

            break;

        case VNC_ENCODING_AUDIO:

            send_ext_audio_ack(vs);

            break;

        case VNC_ENCODING_WMVi:

            vs->features |= VNC_FEATURE_WMVI_MASK;

            break;

        case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:

            vs->tight_compression = (enc & 0x0F);

            break;

        case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:

            vs->tight_quality = (enc & 0x0F);

            break;

        default:

            VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);

            break;

        }

    }

    check_pointer_type_change(&vs->mouse_mode_notifier);

}


static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)

{

    unsigned int i;

    x86_def_t *def;

    char *s = strdup(cpu_model);

    char *featurestr, *name = strtok(s, ",");

    uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;

    uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;

    int family = -1, model = -1, stepping = -1;

    def = NULL;

    for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {

        if (strcmp(name, x86_defs[i].name) == 0) {

            def = &x86_defs[i];

            break;

        }

    }

    if (kvm_enabled() && strcmp(name, "host") == 0) {

        cpu_x86_fill_host(x86_cpu_def);

    } else if (!def) {

        goto error;

    } else {

        memcpy(x86_cpu_def, def, sizeof(*def));

    }

    add_flagname_to_bitmaps("hypervisor", &plus_features,

        &plus_ext_features, &plus_ext2_features, &plus_ext3_features);

    featurestr = strtok(NULL, ",");

    while (featurestr) {

        char *val;

        if (featurestr[0] == '+') {

            add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);

        } else if (featurestr[0] == '-') {

            add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);

        } else if ((val = strchr(featurestr, '='))) {

            *val = 0; val++;

            if (!strcmp(featurestr, "family")) {

                char *err;

                family = strtol(val, &err, 10);

                if (!*val || *err || family < 0) {

                    fprintf(stderr, "bad numerical value %s\n", val);

                    goto error;

                }

                x86_cpu_def->family = family;

            } else if (!strcmp(featurestr, "model")) {

                char *err;

                model = strtol(val, &err, 10);

                if (!*val || *err || model < 0 || model > 0xff) {

                    fprintf(stderr, "bad numerical value %s\n", val);

                    goto error;

                }

                x86_cpu_def->model = model;

            } else if (!strcmp(featurestr, "stepping")) {

                char *err;

                stepping = strtol(val, &err, 10);

                if (!*val || *err || stepping < 0 || stepping > 0xf) {

                    fprintf(stderr, "bad numerical value %s\n", val);

                    goto error;

                }

                x86_cpu_def->stepping = stepping;

            } else if (!strcmp(featurestr, "vendor")) {

                if (strlen(val) != 12) {

                    fprintf(stderr, "vendor string must be 12 chars long\n");

                    goto error;

                }

                x86_cpu_def->vendor1 = 0;

                x86_cpu_def->vendor2 = 0;

                x86_cpu_def->vendor3 = 0;

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

                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);

                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);

                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);

                }

                x86_cpu_def->vendor_override = 1;

            } else if (!strcmp(featurestr, "model_id")) {

                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),

                        val);

            } else {

                fprintf(stderr, "unrecognized feature %s\n", featurestr);

                goto error;

            }

        } else {

            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);

            goto error;

        }

        featurestr = strtok(NULL, ",");

    }

    x86_cpu_def->features |= plus_features;

    x86_cpu_def->ext_features |= plus_ext_features;

    x86_cpu_def->ext2_features |= plus_ext2_features;

    x86_cpu_def->ext3_features |= plus_ext3_features;

    x86_cpu_def->features &= ~minus_features;

    x86_cpu_def->ext_features &= ~minus_ext_features;

    x86_cpu_def->ext2_features &= ~minus_ext2_features;

    x86_cpu_def->ext3_features &= ~minus_ext3_features;

    free(s);

    return 0;

error:

    free(s);

    return -1;

}


static void ppc_spapr_init(ram_addr_t ram_size,

                           const char *boot_device,

                           const char *kernel_filename,

                           const char *kernel_cmdline,

                           const char *initrd_filename,

                           const char *cpu_model)

{

    CPUState *env;

    int i;

    MemoryRegion *sysmem = get_system_memory();

    MemoryRegion *ram = g_new(MemoryRegion, 1);

    target_phys_addr_t rma_alloc_size, rma_size;

    uint32_t initrd_base;

    long kernel_size, initrd_size, fw_size;

    long pteg_shift = 17;

    char *filename;

    spapr = g_malloc0(sizeof(*spapr));

    QLIST_INIT(&spapr->phbs);

    cpu_ppc_hypercall = emulate_spapr_hypercall;

    /* Allocate RMA if necessary */

    rma_alloc_size = kvmppc_alloc_rma("ppc_spapr.rma", sysmem);

    if (rma_alloc_size == -1) {

        hw_error("qemu: Unable to create RMA\n");

        exit(1);

    }

    if (rma_alloc_size && (rma_alloc_size < ram_size)) {

        rma_size = rma_alloc_size;

    } else {

        rma_size = ram_size;

    }

    /* We place the device tree just below either the top of the RMA,

     * or just below 2GB, whichever is lowere, so that it can be

     * processed with 32-bit real mode code if necessary */

    spapr->fdt_addr = MIN(rma_size, 0x80000000) - FDT_MAX_SIZE;

    spapr->rtas_addr = spapr->fdt_addr - RTAS_MAX_SIZE;

    /* init CPUs */

    if (cpu_model == NULL) {

        cpu_model = kvm_enabled() ? "host" : "POWER7";

    }

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

        env = cpu_init(cpu_model);

        if (!env) {

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

            exit(1);

        }

        /* Set time-base frequency to 512 MHz */

        cpu_ppc_tb_init(env, TIMEBASE_FREQ);

        qemu_register_reset((QEMUResetHandler *)&cpu_reset, env);

        env->hreset_vector = 0x60;

        env->hreset_excp_prefix = 0;

        env->gpr[3] = env->cpu_index;

    }

    /* allocate RAM */

    spapr->ram_limit = ram_size;

    if (spapr->ram_limit > rma_alloc_size) {

        ram_addr_t nonrma_base = rma_alloc_size;

        ram_addr_t nonrma_size = spapr->ram_limit - rma_alloc_size;

        memory_region_init_ram(ram, NULL, "ppc_spapr.ram", nonrma_size);

        memory_region_add_subregion(sysmem, nonrma_base, ram);

    }

    /* allocate hash page table.  For now we always make this 16mb,

     * later we should probably make it scale to the size of guest

     * RAM */

    spapr->htab_size = 1ULL << (pteg_shift + 7);

    spapr->htab = qemu_memalign(spapr->htab_size, spapr->htab_size);

    for (env = first_cpu; env != NULL; env = env->next_cpu) {

        env->external_htab = spapr->htab;

        env->htab_base = -1;

        env->htab_mask = spapr->htab_size - 1;

        /* Tell KVM that we're in PAPR mode */

        env->spr[SPR_SDR1] = (unsigned long)spapr->htab |

                             ((pteg_shift + 7) - 18);

        env->spr[SPR_HIOR] = 0;

        if (kvm_enabled()) {

            kvmppc_set_papr(env);

        }

    }

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");

    spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr,

                                           ram_size - spapr->rtas_addr);

    if (spapr->rtas_size < 0) {

        hw_error("qemu: could not load LPAR rtas '%s'\n", filename);

        exit(1);

    }

    g_free(filename);

    /* Set up Interrupt Controller */

    spapr->icp = xics_system_init(XICS_IRQS);

    spapr->next_irq = 16;

    /* Set up VIO bus */

    spapr->vio_bus = spapr_vio_bus_init();

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

        if (serial_hds[i]) {

            spapr_vty_create(spapr->vio_bus, SPAPR_VTY_BASE_ADDRESS + i,

                             serial_hds[i]);

        }

    }

    /* Set up PCI */

    spapr_create_phb(spapr, "pci", SPAPR_PCI_BUID,

                     SPAPR_PCI_MEM_WIN_ADDR,

                     SPAPR_PCI_MEM_WIN_SIZE,

                     SPAPR_PCI_IO_WIN_ADDR);

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

        NICInfo *nd = &nd_table[i];

        if (!nd->model) {

            nd->model = g_strdup("ibmveth");

        }

        if (strcmp(nd->model, "ibmveth") == 0) {

            spapr_vlan_create(spapr->vio_bus, 0x1000 + i, nd);

        } else {

            pci_nic_init_nofail(&nd_table[i], nd->model, NULL);

        }

    }

    for (i = 0; i <= drive_get_max_bus(IF_SCSI); i++) {

        spapr_vscsi_create(spapr->vio_bus, 0x2000 + i);

    }

    if (kernel_filename) {

        uint64_t lowaddr = 0;

        kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,

                               NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);

        if (kernel_size < 0) {

            kernel_size = load_image_targphys(kernel_filename,

                                              KERNEL_LOAD_ADDR,

                                              ram_size - KERNEL_LOAD_ADDR);

        }

        if (kernel_size < 0) {

            fprintf(stderr, "qemu: could not load kernel '%s'\n",

                    kernel_filename);

            exit(1);

        }

        /* load initrd */

        if (initrd_filename) {

            initrd_base = INITRD_LOAD_ADDR;

            initrd_size = load_image_targphys(initrd_filename, initrd_base,

                                              ram_size - initrd_base);

            if (initrd_size < 0) {

                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",

                        initrd_filename);

                exit(1);

            }

        } else {

            initrd_base = 0;

            initrd_size = 0;

        }

        spapr->entry_point = KERNEL_LOAD_ADDR;

    } else {

        if (ram_size < (MIN_RAM_SLOF << 20)) {

            fprintf(stderr, "qemu: pSeries SLOF firmware requires >= "

                    "%ldM guest RAM\n", MIN_RAM_SLOF);

            exit(1);

        }

        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, FW_FILE_NAME);

        fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);

        if (fw_size < 0) {

            hw_error("qemu: could not load LPAR rtas '%s'\n", filename);

            exit(1);

        }

        g_free(filename);

        spapr->entry_point = 0x100;

        initrd_base = 0;

        initrd_size = 0;

        /* SLOF will startup the secondary CPUs using RTAS,

           rather than expecting a kexec() style entry */

        for (env = first_cpu; env != NULL; env = env->next_cpu) {

            env->halted = 1;

        }

    }

    /* Prepare the device tree */

    spapr->fdt_skel = spapr_create_fdt_skel(cpu_model, rma_size,

                                            initrd_base, initrd_size,

                                            boot_device, kernel_cmdline,

                                            pteg_shift + 7);

    assert(spapr->fdt_skel != NULL);

    qemu_register_reset(spapr_reset, spapr);

}


static int swf_write_video(AVFormatContext *s,

                           AVCodecContext *enc, const uint8_t *buf, int size)

{

    ByteIOContext *pb = &s->pb;

    static int tag_id = 0;

    if (enc->frame_number > 1) {

        /* remove the shape */

        put_swf_tag(s, TAG_REMOVEOBJECT);

        put_le16(pb, SHAPE_ID); /* shape ID */

        put_le16(pb, 1); /* depth */

        put_swf_end_tag(s);

        /* free the bitmap */

        put_swf_tag(s, TAG_FREECHARACTER);

        put_le16(pb, BITMAP_ID);

        put_swf_end_tag(s);

    }

    put_swf_tag(s, TAG_JPEG2 | TAG_LONG);

    put_le16(pb, tag_id); /* ID of the image */

    /* a dummy jpeg header seems to be required */

    put_byte(pb, 0xff);

    put_byte(pb, 0xd8);

    put_byte(pb, 0xff);

    put_byte(pb, 0xd9);

    /* write the jpeg image */

    put_buffer(pb, buf, size);

    put_swf_end_tag(s);

    /* draw the shape */

    put_swf_tag(s, TAG_PLACEOBJECT);

    put_le16(pb, SHAPE_ID); /* shape ID */

    put_le16(pb, 1); /* depth */

    put_swf_matrix(pb, 1 << FRAC_BITS, 0, 0, 1 << FRAC_BITS, 0, 0);

    put_swf_end_tag(s);

    /* output the frame */

    put_swf_tag(s, TAG_SHOWFRAME);

    put_swf_end_tag(s);

    put_flush_packet(&s->pb);

    return 0;

}


static int ehci_state_writeback(EHCIQueue *q)

{

    EHCIPacket *p = QTAILQ_FIRST(&q->packets);

    int again = 0;

    /*  Write back the QTD from the QH area */

    assert(p != NULL);

    assert(p->qtdaddr == q->qtdaddr);

    ehci_trace_qtd(q, NLPTR_GET(p->qtdaddr), (EHCIqtd *) &q->qh.next_qtd);

    put_dwords(q->ehci, NLPTR_GET(p->qtdaddr), (uint32_t *) &q->qh.next_qtd,

               sizeof(EHCIqtd) >> 2);

    ehci_free_packet(p);

    /*

     * EHCI specs say go horizontal here.

     *

     * We can also advance the queue here for performance reasons.  We

     * need to take care to only take that shortcut in case we've

     * processed the qtd just written back without errors, i.e. halt

     * bit is clear.

     */

    if (q->qh.token & QTD_TOKEN_HALT) {

        ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);

        again = 1;

    } else {

        ehci_set_state(q->ehci, q->async, EST_ADVANCEQUEUE);

        again = 1;

    }

    return again;

}


static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,

                                  int codec_tag, int format,

                                  int size)

{

    int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);

    if (codec_tag &&

         (codec_tag != format &&

          (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id

                                 : codec_tag != MKTAG('j','p','e','g')))) {

        /* Multiple fourcc, we skip JPEG. This is not correct, we should

         * export it as a separate AVStream but this needs a few changes

         * in the MOV demuxer, patch welcome. */

        av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");

        avio_skip(pb, size);

        return 1;

    }

    if ( codec_tag == AV_RL32("avc1") ||

         codec_tag == AV_RL32("hvc1") ||

         codec_tag == AV_RL32("hev1")

    )

        av_log(c->fc, AV_LOG_WARNING, "Concatenated H.264 or H.265 might not play correctly.\n");

    return 0;

}


static uint32_t cas_check_pvr(PowerPCCPU *cpu, target_ulong *addr,

                              Error **errp)

{

    bool explicit_match = false; /* Matched the CPU's real PVR */

    uint32_t max_compat = cpu->max_compat;

    uint32_t best_compat = 0;

    int i;

    /*

     * We scan the supplied table of PVRs looking for two things

     *   1. Is our real CPU PVR in the list?

     *   2. What's the "best" listed logical PVR

     */

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

        uint32_t pvr, pvr_mask;

        pvr_mask = ldl_be_phys(&address_space_memory, *addr);

        pvr = ldl_be_phys(&address_space_memory, *addr + 4);

        *addr += 8;

        if (~pvr_mask & pvr) {

            break; /* Terminator record */

        }

        if ((cpu->env.spr[SPR_PVR] & pvr_mask) == (pvr & pvr_mask)) {

            explicit_match = true;

        } else {

            if (ppc_check_compat(cpu, pvr, best_compat, max_compat)) {

                best_compat = pvr;

            }

        }

    }

    if ((best_compat == 0) && (!explicit_match || max_compat)) {

        /* We couldn't find a suitable compatibility mode, and either

         * the guest doesn't support "raw" mode for this CPU, or raw

         * mode is disabled because a maximum compat mode is set */

        error_setg(errp, "Couldn't negotiate a suitable PVR during CAS");

        return 0;

    }

    /* Parsing finished */

    trace_spapr_cas_pvr(cpu->compat_pvr, explicit_match, best_compat);

    return best_compat;

}


void ff_slice_thread_free(AVCodecContext *avctx)

{

    SliceThreadContext *c = avctx->internal->thread_ctx;

    int i;

    pthread_mutex_lock(&c->current_job_lock);

    c->done = 1;

    pthread_cond_broadcast(&c->current_job_cond);

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

        pthread_cond_broadcast(&c->progress_cond[i]);

    pthread_mutex_unlock(&c->current_job_lock);

    for (i=0; i<avctx->thread_count; i++)

         pthread_join(c->workers[i], NULL);

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

        pthread_mutex_destroy(&c->progress_mutex[i]);

        pthread_cond_destroy(&c->progress_cond[i]);

    }

    pthread_mutex_destroy(&c->current_job_lock);

    pthread_cond_destroy(&c->current_job_cond);

    pthread_cond_destroy(&c->last_job_cond);

    av_freep(&c->entries);

    av_freep(&c->progress_mutex);

    av_freep(&c->progress_cond);

    av_freep(&c->workers);

    av_freep(&avctx->internal->thread_ctx);

}


RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, RTPPayloadData *rtp_payload_data)

{

    RTPDemuxContext *s;

    s = av_mallocz(sizeof(RTPDemuxContext));

    if (!s)

        return NULL;

    s->payload_type = payload_type;

    s->last_rtcp_ntp_time = AV_NOPTS_VALUE;

    s->first_rtcp_ntp_time = AV_NOPTS_VALUE;

    s->ic = s1;

    s->st = st;

    s->rtp_payload_data = rtp_payload_data;

    rtp_init_statistics(&s->statistics, 0); // do we know the initial sequence from sdp?

    if (!strcmp(ff_rtp_enc_name(payload_type), "MP2T")) {

        s->ts = ff_mpegts_parse_open(s->ic);

        if (s->ts == NULL) {

            av_free(s);

            return NULL;

        }

    } else {

        av_set_pts_info(st, 32, 1, 90000);

        switch(st->codec->codec_id) {

        case CODEC_ID_MPEG1VIDEO:

        case CODEC_ID_MPEG2VIDEO:

        case CODEC_ID_MP2:

        case CODEC_ID_MP3:

        case CODEC_ID_MPEG4:

        case CODEC_ID_H263:

        case CODEC_ID_H264:

            st->need_parsing = AVSTREAM_PARSE_FULL;

            break;

        default:

            if (st->codec->codec_type == CODEC_TYPE_AUDIO) {

                av_set_pts_info(st, 32, 1, st->codec->sample_rate);

            }

            break;

        }

    }

    // needed to send back RTCP RR in RTSP sessions

    s->rtp_ctx = rtpc;

    gethostname(s->hostname, sizeof(s->hostname));

    return s;

}


static int http_send_data(HTTPContext *c, long cur_time)

{

    int len, ret;

    while (c->buffer_ptr >= c->buffer_end) {

        ret = http_prepare_data(c, cur_time);

        if (ret < 0)

            return -1;

        else if (ret == 0) {

            continue;

        } else {

            /* state change requested */

            return 0;

        }

    }

    if (c->buffer_end > c->buffer_ptr) {

        len = write(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr);

        if (len < 0) {

            if (errno != EAGAIN && errno != EINTR) {

                /* error : close connection */

                return -1;

            }

        } else {

            c->buffer_ptr += len;

            c->data_count += len;

            if (c->stream)

                c->stream->bytes_served += len;

        }

    }

    return 0;

}


static void virgl_cmd_resource_unref(VirtIOGPU *g,

                                     struct virtio_gpu_ctrl_command *cmd)

{

    struct virtio_gpu_resource_unref unref;

    VIRTIO_GPU_FILL_CMD(unref);

    trace_virtio_gpu_cmd_res_unref(unref.resource_id);

    virgl_renderer_resource_unref(unref.resource_id);


static void perf_yield(void)

{

    unsigned int i, maxcycles;

    double duration;

    maxcycles = 100000000;

    i = maxcycles;

    Coroutine *coroutine = qemu_coroutine_create(yield_loop);

    g_test_timer_start();

    while (i > 0) {

        qemu_coroutine_enter(coroutine, &i);

    }

    duration = g_test_timer_elapsed();

    g_test_message("Yield %u iterations: %f s\n",

        maxcycles, duration);

}


static void fill_picture_parameters(AVCodecContext *avctx,

                                    struct dxva_context *ctx,

                                    const struct MpegEncContext *s,

                                    DXVA_PictureParameters *pp)

{

    const Picture *current_picture = s->current_picture_ptr;

    int is_field = s->picture_structure != PICT_FRAME;

    memset(pp, 0, sizeof(*pp));

    pp->wDecodedPictureIndex         = ff_dxva2_get_surface_index(ctx, &current_picture->f);

    pp->wDeblockedPictureIndex       = 0;

    if (s->pict_type != AV_PICTURE_TYPE_I)

        pp->wForwardRefPictureIndex  = ff_dxva2_get_surface_index(ctx, &s->last_picture.f);

    else

        pp->wForwardRefPictureIndex  = 0xffff;

    if (s->pict_type == AV_PICTURE_TYPE_B)

        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, &s->next_picture.f);

    else

        pp->wBackwardRefPictureIndex = 0xffff;

    pp->wPicWidthInMBminus1          = s->mb_width  - 1;

    pp->wPicHeightInMBminus1         = (s->mb_height >> is_field) - 1;

    pp->bMacroblockWidthMinus1       = 15;

    pp->bMacroblockHeightMinus1      = 15;

    pp->bBlockWidthMinus1            = 7;

    pp->bBlockHeightMinus1           = 7;

    pp->bBPPminus1                   = 7;

    pp->bPicStructure                = s->picture_structure;

    pp->bSecondField                 = is_field && !s->first_field;

    pp->bPicIntra                    = s->pict_type == AV_PICTURE_TYPE_I;

    pp->bPicBackwardPrediction       = s->pict_type == AV_PICTURE_TYPE_B;

    pp->bBidirectionalAveragingMode  = 0;

    pp->bMVprecisionAndChromaRelation= 0; /* FIXME */

    pp->bChromaFormat                = s->chroma_format;

    pp->bPicScanFixed                = 1;

    pp->bPicScanMethod               = s->alternate_scan ? 1 : 0;

    pp->bPicReadbackRequests         = 0;

    pp->bRcontrol                    = 0;

    pp->bPicSpatialResid8            = 0;

    pp->bPicOverflowBlocks           = 0;

    pp->bPicExtrapolation            = 0;

    pp->bPicDeblocked                = 0;

    pp->bPicDeblockConfined          = 0;

    pp->bPic4MVallowed               = 0;

    pp->bPicOBMC                     = 0;

    pp->bPicBinPB                    = 0;

    pp->bMV_RPS                      = 0;

    pp->bReservedBits                = 0;

    pp->wBitstreamFcodes             = (s->mpeg_f_code[0][0] << 12) |

                                       (s->mpeg_f_code[0][1] <<  8) |

                                       (s->mpeg_f_code[1][0] <<  4) |

                                       (s->mpeg_f_code[1][1]      );

    pp->wBitstreamPCEelements        = (s->intra_dc_precision         << 14) |

                                       (s->picture_structure          << 12) |

                                       (s->top_field_first            << 11) |

                                       (s->frame_pred_frame_dct       << 10) |

                                       (s->concealment_motion_vectors <<  9) |

                                       (s->q_scale_type               <<  8) |

                                       (s->intra_vlc_format           <<  7) |

                                       (s->alternate_scan             <<  6) |

                                       (s->repeat_first_field         <<  5) |

                                       (s->chroma_420_type            <<  4) |

                                       (s->progressive_frame          <<  3);

    pp->bBitstreamConcealmentNeed    = 0;

    pp->bBitstreamConcealmentMethod  = 0;

}


static int virtio_balloon_load(QEMUFile *f, void *opaque, int version_id)

{

    VirtIOBalloon *s = opaque;

    if (version_id != 1)

        return -EINVAL;

    virtio_load(&s->vdev, f);

    s->num_pages = qemu_get_be32(f);

    s->actual = qemu_get_be32(f);

    qemu_get_buffer(f, (uint8_t *)&s->stats_vq_elem, sizeof(VirtQueueElement));

    qemu_get_buffer(f, (uint8_t *)&s->stats_vq_offset, sizeof(size_t));

    qemu_get_buffer(f, (uint8_t *)&s->stats_callback, sizeof(MonitorCompletion));

    qemu_get_buffer(f, (uint8_t *)&s->stats_opaque_callback_data, sizeof(void));

    return 0;

}


static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)

{

    _regs->gpr[1] = infop->start_stack;

#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)

    if (get_ppc64_abi(infop) < 2) {

        _regs->gpr[2] = ldq_raw(infop->entry + 8) + infop->load_bias;

        infop->entry = ldq_raw(infop->entry) + infop->load_bias;

    } else {

        _regs->gpr[12] = infop->entry;  /* r12 set to global entry address */

    }

#endif

    _regs->nip = infop->entry;

}


static int mov_read_custom_2plus(MOVContext *c, AVIOContext *pb, int size)

{

    int64_t end = avio_tell(pb) + size;

    uint8_t *key = NULL, *val = NULL;

    int i;

    AVStream *st;

    MOVStreamContext *sc;

    if (c->fc->nb_streams < 1)

        return 0;

    st = c->fc->streams[c->fc->nb_streams-1];

    sc = st->priv_data;

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

        uint8_t **p;

        uint32_t len, tag;

        if (end - avio_tell(pb) <= 12)

            break;

        len = avio_rb32(pb);

        tag = avio_rl32(pb);

        avio_skip(pb, 4); // flags

        if (len < 12 || len - 12 > end - avio_tell(pb))

            break;

        len -= 12;

        if (tag == MKTAG('n', 'a', 'm', 'e'))

            p = &key;

        else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {

            avio_skip(pb, 4);

            len -= 4;

            p = &val;

        } else

            break;

        *p = av_malloc(len + 1);

        if (!*p)

            break;

        avio_read(pb, *p, len);

        (*p)[len] = 0;

    }

    if (key && val) {

        if (strcmp(key, "iTunSMPB") == 0) {

            int priming, remainder, samples;

            if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){

                if(priming>0 && priming<16384)

                    sc->start_pad = priming;

            }

        }

        if (strcmp(key, "cdec") != 0) {

            av_dict_set(&c->fc->metadata, key, val,

                        AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);

            key = val = NULL;

        }

    }

    avio_seek(pb, end, SEEK_SET);

    av_freep(&key);

    av_freep(&val);

    return 0;

}


static void softusb_usbdev_datain(void *opaque)

{

    MilkymistSoftUsbState *s = opaque;

    USBPacket p;

    p.pid = USB_TOKEN_IN;

    p.devep = 1;

    p.data = s->kbd_usb_buffer;

    p.len = sizeof(s->kbd_usb_buffer);

    s->usbdev->info->handle_data(s->usbdev, &p);

    softusb_kbd_changed(s);

}


static int a52_decode_init(AVCodecContext *avctx)

{

    AC3DecodeState *s = avctx->priv_data;

#ifdef CONFIG_LIBA52BIN

    s->handle = dlopen(liba52name, RTLD_LAZY);

    if (!s->handle)

    {

        av_log( avctx, AV_LOG_ERROR, "A52 library %s could not be opened! \n%s\n", liba52name, dlerror());

        return -1;

    }

    s->a52_init = (a52_state_t* (*)(uint32_t)) dlsymm(s->handle, "a52_init");

    s->a52_samples = (sample_t* (*)(a52_state_t*)) dlsymm(s->handle, "a52_samples");

    s->a52_syncinfo = (int (*)(uint8_t*, int*, int*, int*)) dlsymm(s->handle, "a52_syncinfo");

    s->a52_frame = (int (*)(a52_state_t*, uint8_t*, int*, sample_t*, sample_t)) dlsymm(s->handle, "a52_frame");

    s->a52_block = (int (*)(a52_state_t*)) dlsymm(s->handle, "a52_block");

    s->a52_free = (void (*)(a52_state_t*)) dlsymm(s->handle, "a52_free");

    if (!s->a52_init || !s->a52_samples || !s->a52_syncinfo

        || !s->a52_frame || !s->a52_block || !s->a52_free)

    {

        dlclose(s->handle);

        return -1;

    }

#else

    s->handle = 0;

    s->a52_init = a52_init;

    s->a52_samples = a52_samples;

    s->a52_syncinfo = a52_syncinfo;

    s->a52_frame = a52_frame;

    s->a52_block = a52_block;

    s->a52_free = a52_free;

#endif

    s->state = s->a52_init(0); /* later use CPU flags */

    s->samples = s->a52_samples(s->state);

    s->inbuf_ptr = s->inbuf;

    s->frame_size = 0;

    /* allow downmixing to stereo or mono */

    if (avctx->channels > 0 && avctx->request_channels > 0 &&

            avctx->request_channels < avctx->channels &&

            avctx->request_channels <= 2) {

        avctx->channels = avctx->request_channels;

    }

    return 0;

}


static void release_drive(Object *obj, const char *name, void *opaque)

{

    DeviceState *dev = DEVICE(obj);

    Property *prop = opaque;

    BlockBackend **ptr = qdev_get_prop_ptr(dev, prop);

    if (*ptr) {

        blk_detach_dev(*ptr, dev);

        blockdev_auto_del(*ptr);

    }

}


static inline int decode_picture_parameter_set(H264Context *h, int bit_length){

    MpegEncContext * const s = &h->s;

    unsigned int pps_id= get_ue_golomb(&s->gb);

    PPS *pps;

    if(pps_id>=MAX_PPS_COUNT){

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

        return -1;

    }

    pps = &h->pps_buffer[pps_id];

    pps->sps_id= get_ue_golomb(&s->gb);

    pps->cabac= get_bits1(&s->gb);

    pps->pic_order_present= get_bits1(&s->gb);

    pps->slice_group_count= get_ue_golomb(&s->gb) + 1;

    if(pps->slice_group_count > 1 ){

        pps->mb_slice_group_map_type= get_ue_golomb(&s->gb);

        av_log(h->s.avctx, AV_LOG_ERROR, "FMO not supported\n");

        switch(pps->mb_slice_group_map_type){

        case 0:

#if 0

|   for( i = 0; i <= num_slice_groups_minus1; i++ ) |   |        |

|    run_length[ i ]                                |1  |ue(v)   |

#endif

            break;

        case 2:

#if 0

|   for( i = 0; i < num_slice_groups_minus1; i++ )  |   |        |

|{                                                  |   |        |

|    top_left_mb[ i ]                               |1  |ue(v)   |

|    bottom_right_mb[ i ]                           |1  |ue(v)   |

|   }                                               |   |        |

#endif

            break;

        case 3:

        case 4:

        case 5:

#if 0

|   slice_group_change_direction_flag               |1  |u(1)    |

|   slice_group_change_rate_minus1                  |1  |ue(v)   |

#endif

            break;

        case 6:

#if 0

|   slice_group_id_cnt_minus1                       |1  |ue(v)   |

|   for( i = 0; i <= slice_group_id_cnt_minus1; i++ |   |        |

|)                                                  |   |        |

|    slice_group_id[ i ]                            |1  |u(v)    |

#endif

            break;

        }

    }

    pps->ref_count[0]= get_ue_golomb(&s->gb) + 1;

    pps->ref_count[1]= get_ue_golomb(&s->gb) + 1;

    if(pps->ref_count[0] > 32 || pps->ref_count[1] > 32){

        av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow (pps)\n");

        return -1;

    }

    pps->weighted_pred= get_bits1(&s->gb);

    pps->weighted_bipred_idc= get_bits(&s->gb, 2);

    pps->init_qp= get_se_golomb(&s->gb) + 26;

    pps->init_qs= get_se_golomb(&s->gb) + 26;

    pps->chroma_qp_index_offset= get_se_golomb(&s->gb);

    pps->deblocking_filter_parameters_present= get_bits1(&s->gb);

    pps->constrained_intra_pred= get_bits1(&s->gb);

    pps->redundant_pic_cnt_present = get_bits1(&s->gb);

    pps->transform_8x8_mode= 0;

    h->dequant_coeff_pps= -1; //contents of sps/pps can change even if id doesn't, so reinit

    memset(pps->scaling_matrix4, 16, 6*16*sizeof(uint8_t));

    memset(pps->scaling_matrix8, 16, 2*64*sizeof(uint8_t));

    if(get_bits_count(&s->gb) < bit_length){

        pps->transform_8x8_mode= get_bits1(&s->gb);

        decode_scaling_matrices(h, &h->sps_buffer[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8);

        get_se_golomb(&s->gb);  //second_chroma_qp_index_offset

    }

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

        av_log(h->s.avctx, AV_LOG_DEBUG, "pps:%u sps:%u %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d %s %s %s %s\n",

               pps_id, pps->sps_id,

               pps->cabac ? "CABAC" : "CAVLC",

               pps->slice_group_count,

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

               pps->weighted_pred ? "weighted" : "",

               pps->init_qp, pps->init_qs, pps->chroma_qp_index_offset,

               pps->deblocking_filter_parameters_present ? "LPAR" : "",

               pps->constrained_intra_pred ? "CONSTR" : "",

               pps->redundant_pic_cnt_present ? "REDU" : "",

               pps->transform_8x8_mode ? "8x8DCT" : ""

               );

    }

    return 0;

}


static uint64_t watch_mem_read(void *opaque, hwaddr addr,

                               unsigned size)

{

    check_watchpoint(addr & ~TARGET_PAGE_MASK, size, BP_MEM_READ);

    switch (size) {

    case 1: return ldub_phys(&address_space_memory, addr);

    case 2: return lduw_phys(&address_space_memory, addr);

    case 4: return ldl_phys(&address_space_memory, addr);

    default: abort();

    }

}


static int tcp_open(URLContext *h, const char *uri, int flags)

{

    struct sockaddr_in dest_addr;

    char hostname[1024], *q;

    int port, fd = -1;

    TCPContext *s;

    const char *p;

    fd_set wfds;

    int fd_max, ret;

    struct timeval tv;

    socklen_t optlen;

    s = av_malloc(sizeof(TCPContext));

    if (!s)

        return -ENOMEM;

    h->priv_data = s;

    p = uri;

    if (!strstart(p, "tcp://", &p))

        goto fail;

    q = hostname;

    while (*p != ':' && *p != '/' && *p != '\0') {

        if ((q - hostname) < sizeof(hostname) - 1)

            *q++ = *p;

        p++;

    }

    *q = '\0';

    if (*p != ':')

        goto fail;

    p++;

    port = strtoul(p, (char **)&p, 10);

    if (port <= 0 || port >= 65536)

        goto fail;

    dest_addr.sin_family = AF_INET;

    dest_addr.sin_port = htons(port);

    if (resolve_host(&dest_addr.sin_addr, hostname) < 0)

        goto fail;

    fd = socket(PF_INET, SOCK_STREAM, 0);

    if (fd < 0)

        goto fail;

    fcntl(fd, F_SETFL, O_NONBLOCK);

 redo:

    ret = connect(fd, (struct sockaddr *)&dest_addr,

                  sizeof(dest_addr));

    if (ret < 0) {

        if (errno == EINTR)

            goto redo;

        if (errno != EINPROGRESS)

            goto fail;

        /* wait until we are connected or until abort */

        for(;;) {

            if (url_interrupt_cb()) {

                ret = -EINTR;

                goto fail1;

            }

            fd_max = fd;

            FD_ZERO(&wfds);

            FD_SET(fd, &wfds);

            tv.tv_sec = 0;

            tv.tv_usec = 100 * 1000;

            ret = select(fd_max + 1, NULL, &wfds, NULL, &tv);

            if (ret > 0 && FD_ISSET(fd, &wfds))

                break;

        }

        /* test error */

        optlen = sizeof(ret);

        getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen);

        if (ret != 0)

            goto fail;

    }

    s->fd = fd;

    return 0;

 fail:

    ret = AVERROR_IO;

 fail1:

    if (fd >= 0)

        close(fd);

    av_free(s);

    return ret;

}


static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov)

{

    int max_track_id = 1, i;

    int64_t max_track_len_temp, max_track_len = 0;

    int version;

    for (i = 0; i < mov->nb_streams; i++) {

        if (mov->tracks[i].entry > 0) {

            max_track_len_temp = av_rescale_rnd(mov->tracks[i].track_duration,

                                                MOV_TIMESCALE,

                                                mov->tracks[i].timescale,

                                                AV_ROUND_UP);

            if (max_track_len < max_track_len_temp)

                max_track_len = max_track_len_temp;

            if (max_track_id < mov->tracks[i].track_id)

                max_track_id = mov->tracks[i].track_id;

        }

    }

    version = max_track_len < UINT32_MAX ? 0 : 1;

    (version == 1) ? avio_wb32(pb, 120) : avio_wb32(pb, 108); /* size */

    ffio_wfourcc(pb, "mvhd");

    avio_w8(pb, version);

    avio_wb24(pb, 0); /* flags */

    if (version == 1) {

        avio_wb64(pb, mov->time);

        avio_wb64(pb, mov->time);

    } else {

        avio_wb32(pb, mov->time); /* creation time */

        avio_wb32(pb, mov->time); /* modification time */

    }

    avio_wb32(pb, MOV_TIMESCALE);

    (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */

    avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */

    avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */

    avio_wb16(pb, 0); /* reserved */

    avio_wb32(pb, 0); /* reserved */

    avio_wb32(pb, 0); /* reserved */

    /* Matrix structure */

    avio_wb32(pb, 0x00010000); /* reserved */

    avio_wb32(pb, 0x0); /* reserved */

    avio_wb32(pb, 0x0); /* reserved */

    avio_wb32(pb, 0x0); /* reserved */

    avio_wb32(pb, 0x00010000); /* reserved */

    avio_wb32(pb, 0x0); /* reserved */

    avio_wb32(pb, 0x0); /* reserved */

    avio_wb32(pb, 0x0); /* reserved */

    avio_wb32(pb, 0x40000000); /* reserved */

    avio_wb32(pb, 0); /* reserved (preview time) */

    avio_wb32(pb, 0); /* reserved (preview duration) */

    avio_wb32(pb, 0); /* reserved (poster time) */

    avio_wb32(pb, 0); /* reserved (selection time) */

    avio_wb32(pb, 0); /* reserved (selection duration) */

    avio_wb32(pb, 0); /* reserved (current time) */

    avio_wb32(pb, max_track_id + 1); /* Next track id */

    return 0x6c;

}


static inline void idct4col_put(uint8_t *dest, int line_size, const DCTELEM *col)

{

    int c0, c1, c2, c3, a0, a1, a2, a3;

    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;

    a0 = col[8*0];

    a1 = col[8*2];

    a2 = col[8*4];

    a3 = col[8*6];

    c0 = ((a0 + a2) << (CN_SHIFT - 1)) + (1 << (C_SHIFT - 1));

    c2 = ((a0 - a2) << (CN_SHIFT - 1)) + (1 << (C_SHIFT - 1));

    c1 = a1 * C1 + a3 * C2;

    c3 = a1 * C2 - a3 * C1;

    dest[0] = cm[(c0 + c1) >> C_SHIFT];

    dest += line_size;

    dest[0] = cm[(c2 + c3) >> C_SHIFT];

    dest += line_size;

    dest[0] = cm[(c2 - c3) >> C_SHIFT];

    dest += line_size;

    dest[0] = cm[(c0 - c1) >> C_SHIFT];

}


static void print_final_stats(int64_t total_size)

{

    uint64_t video_size = 0, audio_size = 0, extra_size = 0, other_size = 0;

    uint64_t subtitle_size = 0;

    uint64_t data_size = 0;

    float percent = -1.0;

    int i, j;

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

        OutputStream *ost = output_streams[i];

        switch (ost->st->codec->codec_type) {

            case AVMEDIA_TYPE_VIDEO: video_size += ost->data_size; break;

            case AVMEDIA_TYPE_AUDIO: audio_size += ost->data_size; break;

            case AVMEDIA_TYPE_SUBTITLE: subtitle_size += ost->data_size; break;

            default:                 other_size += ost->data_size; break;

        }

        extra_size += ost->st->codec->extradata_size;

        data_size  += ost->data_size;

    }

    if (data_size && total_size >= data_size)

        percent = 100.0 * (total_size - data_size) / data_size;

    av_log(NULL, AV_LOG_INFO, "\n");

    av_log(NULL, AV_LOG_INFO, "video:%1.0fkB audio:%1.0fkB subtitle:%1.0fkB other streams:%1.0fkB global headers:%1.0fkB muxing overhead: ",

           video_size / 1024.0,

           audio_size / 1024.0,

           subtitle_size / 1024.0,

           other_size / 1024.0,

           extra_size / 1024.0);

    if (percent >= 0.0)

        av_log(NULL, AV_LOG_INFO, "%f%%", percent);

    else

        av_log(NULL, AV_LOG_INFO, "unknown");

    av_log(NULL, AV_LOG_INFO, "\n");

    /* print verbose per-stream stats */

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

        InputFile *f = input_files[i];

        uint64_t total_packets = 0, total_size = 0;

        av_log(NULL, AV_LOG_VERBOSE, "Input file #%d (%s):\n",

               i, f->ctx->filename);

        for (j = 0; j < f->nb_streams; j++) {

            InputStream *ist = input_streams[f->ist_index + j];

            enum AVMediaType type = ist->st->codec->codec_type;

            total_size    += ist->data_size;

            total_packets += ist->nb_packets;

            av_log(NULL, AV_LOG_VERBOSE, "  Input stream #%d:%d (%s): ",

                   i, j, media_type_string(type));

            av_log(NULL, AV_LOG_VERBOSE, "%"PRIu64" packets read (%"PRIu64" bytes); ",

                   ist->nb_packets, ist->data_size);

            if (ist->decoding_needed) {

                av_log(NULL, AV_LOG_VERBOSE, "%"PRIu64" frames decoded",

                       ist->frames_decoded);

                if (type == AVMEDIA_TYPE_AUDIO)

                    av_log(NULL, AV_LOG_VERBOSE, " (%"PRIu64" samples)", ist->samples_decoded);

                av_log(NULL, AV_LOG_VERBOSE, "; ");

            }

            av_log(NULL, AV_LOG_VERBOSE, "\n");

        }

        av_log(NULL, AV_LOG_VERBOSE, "  Total: %"PRIu64" packets (%"PRIu64" bytes) demuxed\n",

               total_packets, total_size);

    }

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

        OutputFile *of = output_files[i];

        uint64_t total_packets = 0, total_size = 0;

        av_log(NULL, AV_LOG_VERBOSE, "Output file #%d (%s):\n",

               i, of->ctx->filename);

        for (j = 0; j < of->ctx->nb_streams; j++) {

            OutputStream *ost = output_streams[of->ost_index + j];

            enum AVMediaType type = ost->st->codec->codec_type;

            total_size    += ost->data_size;

            total_packets += ost->packets_written;

            av_log(NULL, AV_LOG_VERBOSE, "  Output stream #%d:%d (%s): ",

                   i, j, media_type_string(type));

            if (ost->encoding_needed) {

                av_log(NULL, AV_LOG_VERBOSE, "%"PRIu64" frames encoded",

                       ost->frames_encoded);

                if (type == AVMEDIA_TYPE_AUDIO)

                    av_log(NULL, AV_LOG_VERBOSE, " (%"PRIu64" samples)", ost->samples_encoded);

                av_log(NULL, AV_LOG_VERBOSE, "; ");

            }

            av_log(NULL, AV_LOG_VERBOSE, "%"PRIu64" packets muxed (%"PRIu64" bytes); ",

                   ost->packets_written, ost->data_size);

            av_log(NULL, AV_LOG_VERBOSE, "\n");

        }

        av_log(NULL, AV_LOG_VERBOSE, "  Total: %"PRIu64" packets (%"PRIu64" bytes) muxed\n",

               total_packets, total_size);

    }

    if(video_size + data_size + audio_size + subtitle_size + extra_size == 0){

        av_log(NULL, AV_LOG_WARNING, "Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)\n");

    }

}


static void read_sbr_channel_pair_element(AACContext *ac,

                                          SpectralBandReplication *sbr,

                                          GetBitContext *gb)

{

    if (get_bits1(gb))    // bs_data_extra

        skip_bits(gb, 8); // bs_reserved

    if ((sbr->bs_coupling = get_bits1(gb))) {

        read_sbr_grid(ac, sbr, gb, &sbr->data[0]);

        copy_sbr_grid(&sbr->data[1], &sbr->data[0]);

        read_sbr_dtdf(sbr, gb, &sbr->data[0]);

        read_sbr_dtdf(sbr, gb, &sbr->data[1]);

        read_sbr_invf(sbr, gb, &sbr->data[0]);

        memcpy(sbr->data[1].bs_invf_mode[1], sbr->data[1].bs_invf_mode[0], sizeof(sbr->data[1].bs_invf_mode[0]));

        memcpy(sbr->data[1].bs_invf_mode[0], sbr->data[0].bs_invf_mode[0], sizeof(sbr->data[1].bs_invf_mode[0]));

        read_sbr_envelope(sbr, gb, &sbr->data[0], 0);

        read_sbr_noise(sbr, gb, &sbr->data[0], 0);

        read_sbr_envelope(sbr, gb, &sbr->data[1], 1);

        read_sbr_noise(sbr, gb, &sbr->data[1], 1);

    } else {

        read_sbr_grid(ac, sbr, gb, &sbr->data[0]);

        read_sbr_grid(ac, sbr, gb, &sbr->data[1]);

        read_sbr_dtdf(sbr, gb, &sbr->data[0]);

        read_sbr_dtdf(sbr, gb, &sbr->data[1]);

        read_sbr_invf(sbr, gb, &sbr->data[0]);

        read_sbr_invf(sbr, gb, &sbr->data[1]);

        read_sbr_envelope(sbr, gb, &sbr->data[0], 0);

        read_sbr_envelope(sbr, gb, &sbr->data[1], 1);

        read_sbr_noise(sbr, gb, &sbr->data[0], 0);

        read_sbr_noise(sbr, gb, &sbr->data[1], 1);

    }

    if ((sbr->data[0].bs_add_harmonic_flag = get_bits1(gb)))

        get_bits1_vector(gb, sbr->data[0].bs_add_harmonic, sbr->n[1]);

    if ((sbr->data[1].bs_add_harmonic_flag = get_bits1(gb)))

        get_bits1_vector(gb, sbr->data[1].bs_add_harmonic, sbr->n[1]);

}


static void qtrle_decode_16bpp(QtrleContext *s, int stream_ptr, int row_ptr, int lines_to_change)

{

    int rle_code;

    int pixel_ptr;

    int row_inc = s->frame.linesize[0];

    unsigned short rgb16;

    unsigned char *rgb = s->frame.data[0];

    int pixel_limit = s->frame.linesize[0] * s->avctx->height;

    while (lines_to_change--) {

        CHECK_STREAM_PTR(2);

        pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 2;

        while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {

            if (rle_code == 0) {

                /* there's another skip code in the stream */

                CHECK_STREAM_PTR(1);

                pixel_ptr += (s->buf[stream_ptr++] - 1) * 2;

                CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */

            } else if (rle_code < 0) {

                /* decode the run length code */

                rle_code = -rle_code;

                CHECK_STREAM_PTR(2);

                rgb16 = AV_RB16(&s->buf[stream_ptr]);

                stream_ptr += 2;

                CHECK_PIXEL_PTR(rle_code * 2);

                while (rle_code--) {

                    *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;

                    pixel_ptr += 2;

                }

            } else {

                CHECK_STREAM_PTR(rle_code * 2);

                CHECK_PIXEL_PTR(rle_code * 2);

                /* copy pixels directly to output */

                while (rle_code--) {

                    rgb16 = AV_RB16(&s->buf[stream_ptr]);

                    stream_ptr += 2;

                    *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;

                    pixel_ptr += 2;

                }

            }

        }

        row_ptr += row_inc;

    }

}


static void v9fs_mknod(void *opaque)

{

    int mode;

    gid_t gid;

    int32_t fid;

    V9fsQID qid;

    int err = 0;

    int major, minor;

    size_t offset = 7;

    V9fsString name;

    struct stat stbuf;

    V9fsFidState *fidp;

    V9fsPDU *pdu = opaque;

    V9fsState *s = pdu->s;

    pdu_unmarshal(pdu, offset, "dsdddd", &fid, &name, &mode,

                  &major, &minor, &gid);

    fidp = get_fid(pdu, fid);

    if (fidp == NULL) {

        err = -ENOENT;

        goto out_nofid;

    }

    err = v9fs_co_mknod(pdu, fidp, &name, fidp->uid, gid,

                        makedev(major, minor), mode, &stbuf);

    if (err < 0) {

        goto out;

    }

    stat_to_qid(&stbuf, &qid);

    err = offset;

    err += pdu_marshal(pdu, offset, "Q", &qid);

out:

    put_fid(pdu, fidp);

out_nofid:

    trace_v9fs_mknod_return(pdu->tag, pdu->id, qid.type, qid.version, qid.path);

    complete_pdu(s, pdu, err);

    v9fs_string_free(&name);

}


void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
{
    cpsr_write(env, val, CPSR_ERET_MASK, CPSRWriteExceptionReturn);
    arm_call_el_change_hook(arm_env_get_cpu(env));
}


static void vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,

                                        int jobnr, int threadnr)

{

    decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1);

}


static void test_parse_path_subprocess(void)

{

    /* All these should work without issue */

    qemu_set_log_filename("/tmp/qemu.log");

    qemu_set_log_filename("/tmp/qemu-%d.log");

    qemu_set_log_filename("/tmp/qemu.log.%d");

}


static inline void RENAME(hScale)(int16_t *dst, int dstW, uint8_t *src, int srcW, int xInc,

				  int16_t *filter, int16_t *filterPos, long filterSize)

{

#ifdef HAVE_MMX

	assert(filterSize % 4 == 0 && filterSize>0);

	if(filterSize==4) // allways true for upscaling, sometimes for down too

	{

		long counter= -2*dstW;

		filter-= counter*2;

		filterPos-= counter/2;

		dst-= counter/2;

		asm volatile(

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

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

			"push %%"REG_BP"		\n\t" // we use 7 regs here ...

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

			ASMALIGN16

			"1:				\n\t"

			"movzwl (%2, %%"REG_BP"), %%eax	\n\t"

			"movzwl 2(%2, %%"REG_BP"), %%ebx\n\t"

			"movq (%1, %%"REG_BP", 4), %%mm1\n\t"

			"movq 8(%1, %%"REG_BP", 4), %%mm3\n\t"

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

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

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

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

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

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

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

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

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

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

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

			"movd %%mm0, (%4, %%"REG_BP")	\n\t"

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

			" jnc 1b			\n\t"

			"pop %%"REG_BP"			\n\t"

			: "+a" (counter)

			: "c" (filter), "d" (filterPos), "S" (src), "D" (dst)

			: "%"REG_b

		);

	}

	else if(filterSize==8)

	{

		long counter= -2*dstW;

		filter-= counter*4;

		filterPos-= counter/2;

		dst-= counter/2;

		asm volatile(

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

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

			"push %%"REG_BP"		\n\t" // we use 7 regs here ...

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

			ASMALIGN16

			"1:				\n\t"

			"movzwl (%2, %%"REG_BP"), %%eax	\n\t"

			"movzwl 2(%2, %%"REG_BP"), %%ebx\n\t"

			"movq (%1, %%"REG_BP", 8), %%mm1\n\t"

			"movq 16(%1, %%"REG_BP", 8), %%mm3\n\t"

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

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

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

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

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

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

			"movq 8(%1, %%"REG_BP", 8), %%mm1\n\t"

			"movq 24(%1, %%"REG_BP", 8), %%mm5\n\t"

			"movd 4(%3, %%"REG_a"), %%mm4	\n\t"

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

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

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

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

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

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

			"paddd %%mm5, %%mm3		\n\t"

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

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

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

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

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

			"movd %%mm0, (%4, %%"REG_BP")	\n\t"

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

			" jnc 1b			\n\t"

			"pop %%"REG_BP"			\n\t"

			: "+a" (counter)

			: "c" (filter), "d" (filterPos), "S" (src), "D" (dst)

			: "%"REG_b

		);

	}

	else

	{

		uint8_t *offset = src+filterSize;

		long counter= -2*dstW;

//		filter-= counter*filterSize/2;

		filterPos-= counter/2;

		dst-= counter/2;

		asm volatile(

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

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

			ASMALIGN16

			"1:				\n\t"

			"mov %2, %%"REG_c"		\n\t"

			"movzwl (%%"REG_c", %0), %%eax	\n\t"

			"movzwl 2(%%"REG_c", %0), %%ebx	\n\t"

			"mov %5, %%"REG_c"		\n\t"

			"pxor %%mm4, %%mm4		\n\t"

			"pxor %%mm5, %%mm5		\n\t"

			"2:				\n\t"

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

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

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

			"movd (%%"REG_c", %%"REG_b"), %%mm2\n\t"

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

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

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

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

			"paddd %%mm3, %%mm5		\n\t"

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

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

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

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

			" jb 2b				\n\t"

			"add %6, %1			\n\t"

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

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

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

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

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

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

			"movd %%mm4, (%%"REG_a", %0)	\n\t"

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

			" jnc 1b			\n\t"

			: "+r" (counter), "+r" (filter)

			: "m" (filterPos), "m" (dst), "m"(offset),

			  "m" (src), "r" (filterSize*2)

			: "%"REG_b, "%"REG_a, "%"REG_c

		);

	}

#else

#ifdef HAVE_ALTIVEC

	hScale_altivec_real(dst, dstW, src, srcW, xInc, filter, filterPos, filterSize);

#else

	int i;

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

	{

		int j;

		int srcPos= filterPos[i];

		int val=0;

//		printf("filterPos: %d\n", filterPos[i]);

		for(j=0; j<filterSize; j++)

		{

//			printf("filter: %d, src: %d\n", filter[i], src[srcPos + j]);

			val += ((int)src[srcPos + j])*filter[filterSize*i + j];

		}

//		filter += hFilterSize;

		dst[i] = FFMIN(FFMAX(0, val>>7), (1<<15)-1); // the cubic equation does overflow ...

//		dst[i] = val>>7;

	}

#endif

#endif

}


int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples)

{

    int i, nb_samples1;

    short *bufin[2];

    short *bufout[2];

    short *buftmp2[2], *buftmp3[2];

    int lenout;

    if (s->input_channels == s->output_channels && s->ratio == 1.0 && 0) {

        /* nothing to do */

        memcpy(output, input, nb_samples * s->input_channels * sizeof(short));

        return nb_samples;

    }

    /* XXX: move those malloc to resample init code */

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

        bufin[i]= (short*) av_malloc( (nb_samples + s->temp_len) * sizeof(short) );

        memcpy(bufin[i], s->temp[i], s->temp_len * sizeof(short));

        buftmp2[i] = bufin[i] + s->temp_len;

    }

    /* make some zoom to avoid round pb */

    lenout= (int)(4*nb_samples * s->ratio) + 16;

    bufout[0]= (short*) av_malloc( lenout * sizeof(short) );

    bufout[1]= (short*) av_malloc( lenout * sizeof(short) );

    if (s->input_channels == 2 &&

        s->output_channels == 1) {

        buftmp3[0] = output;

        stereo_to_mono(buftmp2[0], input, nb_samples);

    } else if (s->output_channels >= 2 && s->input_channels == 1) {

        buftmp3[0] = bufout[0];

        memcpy(buftmp2[0], input, nb_samples*sizeof(short));

    } else if (s->output_channels >= 2) {

        buftmp3[0] = bufout[0];

        buftmp3[1] = bufout[1];

        stereo_split(buftmp2[0], buftmp2[1], input, nb_samples);

    } else {

        buftmp3[0] = output;

        memcpy(buftmp2[0], input, nb_samples*sizeof(short));

    }

    nb_samples += s->temp_len;

    /* resample each channel */

    nb_samples1 = 0; /* avoid warning */

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

        int consumed;

        int is_last= i+1 == s->filter_channels;

        nb_samples1 = av_resample(s->resample_context, buftmp3[i], bufin[i], &consumed, nb_samples, lenout, is_last);

        s->temp_len= nb_samples - consumed;

        s->temp[i]= av_realloc(s->temp[i], s->temp_len*sizeof(short));

        memcpy(s->temp[i], bufin[i] + consumed, s->temp_len*sizeof(short));

    }

    if (s->output_channels == 2 && s->input_channels == 1) {

        mono_to_stereo(output, buftmp3[0], nb_samples1);

    } else if (s->output_channels == 2) {

        stereo_mux(output, buftmp3[0], buftmp3[1], nb_samples1);

    } else if (s->output_channels == 6) {

        ac3_5p1_mux(output, buftmp3[0], buftmp3[1], nb_samples1);

    }

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

        av_free(bufin[i]);

    av_free(bufout[0]);

    av_free(bufout[1]);

    return nb_samples1;

}


static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr,

                        int nb_jobs)

{

    TransContext *s = ctx->priv;

    ThreadData *td = arg;

    AVFrame *out = td->out;

    AVFrame *in = td->in;

    int plane;

    for (plane = 0; out->data[plane]; plane++) {

        int hsub    = plane == 1 || plane == 2 ? s->hsub : 0;

        int vsub    = plane == 1 || plane == 2 ? s->vsub : 0;

        int pixstep = s->pixsteps[plane];

        int inh     = AV_CEIL_RSHIFT(in->height, vsub);

        int outw    = AV_CEIL_RSHIFT(out->width,  hsub);

        int outh    = AV_CEIL_RSHIFT(out->height, vsub);

        int start   = (outh *  jobnr   ) / nb_jobs;

        int end     = (outh * (jobnr+1)) / nb_jobs;

        uint8_t *dst, *src;

        int dstlinesize, srclinesize;

        int x, y;

        dstlinesize = out->linesize[plane];

        dst         = out->data[plane] + start * dstlinesize;

        src         = in->data[plane];

        srclinesize = in->linesize[plane];

        if (s->dir & 1) {

            src         += in->linesize[plane] * (inh - 1);

            srclinesize *= -1;

        }

        if (s->dir & 2) {

            dst          = out->data[plane] + dstlinesize * (outh - start - 1);

            dstlinesize *= -1;

        }

        for (y = start; y < end - 7; y += 8) {

            for (x = 0; x < outw - 7; x += 8) {

                s->transpose_8x8(src + x * srclinesize + y * pixstep,

                                 srclinesize,

                                 dst + (y - start) * dstlinesize + x * pixstep,

                                 dstlinesize);

            }

            if (outw - x > 0 && end - y > 0)

                s->transpose_block(src + x * srclinesize + y * pixstep,

                                   srclinesize,

                                   dst + (y - start) * dstlinesize + x * pixstep,

                                   dstlinesize, outw - x, end - y);

        }

        if (end - y > 0)

            s->transpose_block(src + 0 * srclinesize + y * pixstep,

                               srclinesize,

                               dst + (y - start) * dstlinesize + 0 * pixstep,

                               dstlinesize, outw, end - y);

    }

    return 0;

}


static int expand_rle_row(const uint8_t *in_buf, const uint8_t* in_end,

            unsigned char *out_buf, uint8_t* out_end, int pixelstride)

{

    unsigned char pixel, count;

    unsigned char *orig = out_buf;

    while (1) {

        if(in_buf + 1 > in_end) return -1;

        pixel = bytestream_get_byte(&in_buf);

        if (!(count = (pixel & 0x7f))) {

            return (out_buf - orig) / pixelstride;

        }

        /* Check for buffer overflow. */

        if(out_buf + pixelstride * count >= out_end) return -1;

        if (pixel & 0x80) {

            while (count--) {

                *out_buf = bytestream_get_byte(&in_buf);

                out_buf += pixelstride;

            }

        } else {

            pixel = bytestream_get_byte(&in_buf);

            while (count--) {

                *out_buf = pixel;

                out_buf += pixelstride;

            }

        }

    }

}


static void encode_exponents_blk_ch(uint8_t *exp,

                                    int nb_exps, int exp_strategy,

                                    uint8_t *num_exp_groups)

{

    int group_size, nb_groups, i, j, k, exp_min;

    group_size = exp_strategy + (exp_strategy == EXP_D45);

    *num_exp_groups = (nb_exps + (group_size * 3) - 4) / (3 * group_size);

    nb_groups = *num_exp_groups * 3;

    /* for each group, compute the minimum exponent */

    if (exp_strategy > EXP_D15) {

    k = 1;

    for (i = 1; i <= nb_groups; i++) {

        exp_min = exp[k];

        assert(exp_min >= 0 && exp_min <= 24);

        for (j = 1; j < group_size; j++) {

            if (exp[k+j] < exp_min)

                exp_min = exp[k+j];

        }

        exp[i] = exp_min;

        k += group_size;

    }

    }

    /* constraint for DC exponent */

    if (exp[0] > 15)

        exp[0] = 15;

    /* decrease the delta between each groups to within 2 so that they can be

       differentially encoded */

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

        exp[i] = FFMIN(exp[i], exp[i-1] + 2);

    for (i = nb_groups-1; i >= 0; i--)

        exp[i] = FFMIN(exp[i], exp[i+1] + 2);

    /* now we have the exponent values the decoder will see */

    if (exp_strategy > EXP_D15) {

    k = nb_groups * group_size;

    for (i = nb_groups; i > 0; i--) {

        for (j = 0; j < group_size; j++)

            exp[k-j] = exp[i];

        k -= group_size;

    }

    }

}


static void ac3_update_bap_counts_c(uint16_t mant_cnt[16], uint8_t *bap,

                                    int len)

{

    while (len-- >= 0)

        mant_cnt[bap[len]]++;

}


static av_cold int adpcm_decode_init(AVCodecContext * avctx)

{

    ADPCMDecodeContext *c = avctx->priv_data;

    unsigned int min_channels = 1;

    unsigned int max_channels = 2;

    switch(avctx->codec->id) {

    case AV_CODEC_ID_ADPCM_DTK:

    case AV_CODEC_ID_ADPCM_EA:

        min_channels = 2;

        break;

    case AV_CODEC_ID_ADPCM_AFC:

    case AV_CODEC_ID_ADPCM_EA_R1:

    case AV_CODEC_ID_ADPCM_EA_R2:

    case AV_CODEC_ID_ADPCM_EA_R3:

    case AV_CODEC_ID_ADPCM_EA_XAS:

        max_channels = 6;

        break;

    case AV_CODEC_ID_ADPCM_THP:

    case AV_CODEC_ID_ADPCM_THP_LE:

        max_channels = 10;

        break;

    }

    if (avctx->channels < min_channels || avctx->channels > max_channels) {

        av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");

        return AVERROR(EINVAL);

    }

    switch(avctx->codec->id) {

    case AV_CODEC_ID_ADPCM_CT:

        c->status[0].step = c->status[1].step = 511;

        break;

    case AV_CODEC_ID_ADPCM_IMA_WAV:

        if (avctx->bits_per_coded_sample < 2 || avctx->bits_per_coded_sample > 5)

            return AVERROR_INVALIDDATA;

        break;

    case AV_CODEC_ID_ADPCM_IMA_APC:

        if (avctx->extradata && avctx->extradata_size >= 8) {

            c->status[0].predictor = AV_RL32(avctx->extradata);

            c->status[1].predictor = AV_RL32(avctx->extradata + 4);

        }

        break;

    case AV_CODEC_ID_ADPCM_IMA_WS:

        if (avctx->extradata && avctx->extradata_size >= 2)

            c->vqa_version = AV_RL16(avctx->extradata);

        break;

    default:

        break;

    }

    switch(avctx->codec->id) {

        case AV_CODEC_ID_ADPCM_IMA_QT:

        case AV_CODEC_ID_ADPCM_IMA_WAV:

        case AV_CODEC_ID_ADPCM_4XM:

        case AV_CODEC_ID_ADPCM_XA:

        case AV_CODEC_ID_ADPCM_EA_R1:

        case AV_CODEC_ID_ADPCM_EA_R2:

        case AV_CODEC_ID_ADPCM_EA_R3:

        case AV_CODEC_ID_ADPCM_EA_XAS:

        case AV_CODEC_ID_ADPCM_THP:

        case AV_CODEC_ID_ADPCM_THP_LE:

        case AV_CODEC_ID_ADPCM_AFC:

        case AV_CODEC_ID_ADPCM_DTK:

            avctx->sample_fmt = AV_SAMPLE_FMT_S16P;

            break;

        case AV_CODEC_ID_ADPCM_IMA_WS:

            avctx->sample_fmt = c->vqa_version == 3 ? AV_SAMPLE_FMT_S16P :

                                                      AV_SAMPLE_FMT_S16;

            break;

        default:

            avctx->sample_fmt = AV_SAMPLE_FMT_S16;

    }

    return 0;

}


static void test2_fill_picture(AVFilterContext *ctx, AVFrame *frame)

{

    TestSourceContext *s = ctx->priv;

    FFDrawColor color;

    unsigned alpha = (uint32_t)s->alpha << 24;

    /* colored background */

    {

        unsigned i, x = 0, x2;

        x = 0;

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

            x2 = av_rescale(i, s->w, 6);

            x2 = ff_draw_round_to_sub(&s->draw, 0, 0, x2);

            set_color(s, &color, ((i & 1) ? 0xFF0000 : 0) |

                                 ((i & 2) ? 0x00FF00 : 0) |

                                 ((i & 4) ? 0x0000FF : 0) |

                                 alpha);

            ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,

                              x, 0, x2 - x, frame->height);

            x = x2;

        }

    }

    /* oblique gradient */

    /* note: too slow if using blending */

    if (s->h >= 64) {

        unsigned x, dx, y0, y, g0, g;

        dx = ff_draw_round_to_sub(&s->draw, 0, +1, 1);

        y0 = av_rescale_q(s->pts, s->time_base, av_make_q(2, s->h - 16));

        g0 = av_rescale_q(s->pts, s->time_base, av_make_q(1, 128));

        for (x = 0; x < s->w; x += dx) {

            g = (av_rescale(x, 6 * 256, s->w) + g0) % (6 * 256);

            set_color(s, &color, color_gradient(g) | alpha);

            y = y0 + av_rescale(x, s->h / 2, s->w);

            y %= 2 * (s->h - 16);

            if (y > s->h - 16)

                y = 2 * (s->h - 16) - y;

            y = ff_draw_round_to_sub(&s->draw, 1, 0, y);

            ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,

                              x, y, dx, 16);

        }

    }

    /* top right: draw clock hands */

    if (s->w >= 64 && s->h >= 64) {

        int l = (FFMIN(s->w, s->h) - 32) >> 1;

        int steps = FFMAX(4, l >> 5);

        int xc = (s->w >> 2) + (s->w >> 1);

        int yc = (s->h >> 2);

        int cycle = l << 2;

        int pos, xh, yh;

        int c, i;

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

            set_color(s, &color, (0xBBBBBB ^ (0xFF << (c << 3))) | alpha);

            pos = av_rescale_q(s->pts, s->time_base, av_make_q(64 >> (c << 1), cycle)) % cycle;

            xh = pos < 1 * l ? pos :

                 pos < 2 * l ? l :

                 pos < 3 * l ? 3 * l - pos : 0;

            yh = pos < 1 * l ? 0 :

                 pos < 2 * l ? pos - l :

                 pos < 3 * l ? l :

                               cycle - pos;

            xh -= l >> 1;

            yh -= l >> 1;

            for (i = 1; i <= steps; i++) {

                int x = av_rescale(xh, i, steps) + xc;

                int y = av_rescale(yh, i, steps) + yc;

                x = ff_draw_round_to_sub(&s->draw, 0, -1, x);

                y = ff_draw_round_to_sub(&s->draw, 1, -1, y);

                ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,

                                  x, y, 8, 8);

            }

        }

    }

    /* bottom left: beating rectangles */

    if (s->w >= 64 && s->h >= 64) {

        int l = (FFMIN(s->w, s->h) - 16) >> 2;

        int cycle = l << 3;

        int xc = (s->w >> 2);

        int yc = (s->h >> 2) + (s->h >> 1);

        int xm1 = ff_draw_round_to_sub(&s->draw, 0, -1, xc - 8);

        int xm2 = ff_draw_round_to_sub(&s->draw, 0, +1, xc + 8);

        int ym1 = ff_draw_round_to_sub(&s->draw, 1, -1, yc - 8);

        int ym2 = ff_draw_round_to_sub(&s->draw, 1, +1, yc + 8);

        int size, step, x1, x2, y1, y2;

        size = av_rescale_q(s->pts, s->time_base, av_make_q(4, cycle));

        step = size / l;

        size %= l;

        if (step & 1)

            size = l - size;

        step = (step >> 1) & 3;

        set_color(s, &color, 0xFF808080);

        x1 = ff_draw_round_to_sub(&s->draw, 0, -1, xc - 4 - size);

        x2 = ff_draw_round_to_sub(&s->draw, 0, +1, xc + 4 + size);

        y1 = ff_draw_round_to_sub(&s->draw, 1, -1, yc - 4 - size);

        y2 = ff_draw_round_to_sub(&s->draw, 1, +1, yc + 4 + size);

        if (step == 0 || step == 2)

            ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,

                              x1, ym1, x2 - x1, ym2 - ym1);

        if (step == 1 || step == 2)

            ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,

                              xm1, y1, xm2 - xm1, y2 - y1);

        if (step == 3)

            ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,

                              x1, y1, x2 - x1, y2 - y1);

    }

    /* bottom right: checker with random noise */

    {

        unsigned xmin = av_rescale(5, s->w, 8);

        unsigned xmax = av_rescale(7, s->w, 8);

        unsigned ymin = av_rescale(5, s->h, 8);

        unsigned ymax = av_rescale(7, s->h, 8);

        unsigned x, y, i, r;

        uint8_t alpha[256];

        r = s->pts;

        for (y = ymin; y < ymax - 15; y += 16) {

            for (x = xmin; x < xmax - 15; x += 16) {

                if ((x ^ y) & 16)

                    continue;

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

                    r = r * 1664525 + 1013904223;

                    alpha[i] = r >> 24;

                }

                set_color(s, &color, 0xFF00FF80);

                ff_blend_mask(&s->draw, &color, frame->data, frame->linesize,

                                   frame->width, frame->height,

                                   alpha, 16, 16, 16, 3, 0, x, y);

            }

        }

    }

    /* bouncing square */

    if (s->w >= 16 && s->h >= 16) {

        unsigned w = s->w - 8;

        unsigned h = s->h - 8;

        unsigned x = av_rescale_q(s->pts, s->time_base, av_make_q(233, 55 * w)) % (w << 1);

        unsigned y = av_rescale_q(s->pts, s->time_base, av_make_q(233, 89 * h)) % (h << 1);

        if (x > w)

            x = (w << 1) - x;

        if (y > h)

            y = (h << 1) - y;

        x = ff_draw_round_to_sub(&s->draw, 0, -1, x);

        y = ff_draw_round_to_sub(&s->draw, 1, -1, y);

        set_color(s, &color, 0xFF8000FF);

        ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,

                          x, y, 8, 8);

    }

    /* top right: draw frame time and frame number */

    {

        char buf[256];

        unsigned time;

        time = av_rescale_q(s->pts, s->time_base, av_make_q(1, 1000)) % 86400000;

        set_color(s, &color, 0xC0000000);

        ff_blend_rectangle(&s->draw, &color, frame->data, frame->linesize,

                           frame->width, frame->height,

                           2, 2, 100, 36);

        set_color(s, &color, 0xFFFF8000);

        snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%03d\n%12"PRIi64,

                 time / 3600000, (time / 60000) % 60, (time / 1000) % 60,

                 time % 1000, s->pts);

        draw_text(s, frame, &color, 4, 4, buf);

    }

}


static int iv_decode_frame(AVCodecContext *avctx,

                           const uint8_t *buf, int buf_size)

{

    Indeo3DecodeContext *s = avctx->priv_data;

    unsigned int image_width, image_height,

                 chroma_width, chroma_height;

    unsigned long flags, cb_offset, data_size,

                  y_offset, v_offset, u_offset, mc_vector_count;

    const uint8_t *hdr_pos, *buf_pos;

    buf_pos = buf;

    buf_pos += 18; /* skip OS header (16 bytes) and version number */

    flags = bytestream_get_le16(&buf_pos);

    data_size = bytestream_get_le32(&buf_pos);

    cb_offset = *buf_pos++;

    buf_pos += 3; /* skip reserved byte and checksum */

    image_height = bytestream_get_le16(&buf_pos);

    image_width  = bytestream_get_le16(&buf_pos);

    if(avcodec_check_dimensions(avctx, image_width, image_height))

        return -1;

    chroma_height = ((image_height >> 2) + 3) & 0x7ffc;

    chroma_width = ((image_width >> 2) + 3) & 0x7ffc;

    y_offset = bytestream_get_le32(&buf_pos);

    v_offset = bytestream_get_le32(&buf_pos);

    u_offset = bytestream_get_le32(&buf_pos);

    buf_pos += 4; /* reserved */

    hdr_pos = buf_pos;

    if(data_size == 0x80) return 4;

    if(FFMAX3(y_offset, v_offset, u_offset) >= buf_size-16) {

        av_log(s->avctx, AV_LOG_ERROR, "y/u/v offset outside buffer\n");

        return -1;

    if(flags & 0x200) {

        s->cur_frame = s->iv_frame + 1;

        s->ref_frame = s->iv_frame;

    } else {

        s->cur_frame = s->iv_frame;

        s->ref_frame = s->iv_frame + 1;

    buf_pos = buf + 16 + y_offset;

    mc_vector_count = bytestream_get_le32(&buf_pos);

    if(2LL*mc_vector_count >= buf_size-16-y_offset) {

        av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n");

        return -1;

    iv_Decode_Chunk(s, s->cur_frame->Ybuf, s->ref_frame->Ybuf, image_width,

                    image_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,

                    FFMIN(image_width, 160));

    if (!(s->avctx->flags & CODEC_FLAG_GRAY))

    {

        buf_pos = buf + 16 + v_offset;

        mc_vector_count = bytestream_get_le32(&buf_pos);

        if(2LL*mc_vector_count >= buf_size-16-v_offset) {

            av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n");

            return -1;

        iv_Decode_Chunk(s, s->cur_frame->Vbuf, s->ref_frame->Vbuf, chroma_width,

                chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,

                FFMIN(chroma_width, 40));

        buf_pos = buf + 16 + u_offset;

        mc_vector_count = bytestream_get_le32(&buf_pos);

        if(2LL*mc_vector_count >= buf_size-16-u_offset) {

            av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n");

            return -1;

        iv_Decode_Chunk(s, s->cur_frame->Ubuf, s->ref_frame->Ubuf, chroma_width,

                chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,

                FFMIN(chroma_width, 40));

    return 8;


static void output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost)

{

    int ret = 0;

    /* apply the output bitstream filters, if any */

    if (ost->nb_bitstream_filters) {

        int idx;

        ret = av_bsf_send_packet(ost->bsf_ctx[0], pkt);

        if (ret < 0)

            goto finish;

        idx = 1;

        while (idx) {

            /* get a packet from the previous filter up the chain */

            ret = av_bsf_receive_packet(ost->bsf_ctx[idx - 1], pkt);

            /* HACK! - aac_adtstoasc updates extradata after filtering the first frame when

             * the api states this shouldn't happen after init(). Propagate it here to the

             * muxer and to the next filters in the chain to workaround this.

             * TODO/FIXME - Make aac_adtstoasc use new packet side data instead of changing

             * par_out->extradata and adapt muxers accordingly to get rid of this. */

            if (!(ost->bsf_extradata_updated[idx - 1] & 1)) {

                ret = avcodec_parameters_copy(ost->st->codecpar, ost->bsf_ctx[idx - 1]->par_out);

                if (ret < 0)

                    goto finish;

                ost->bsf_extradata_updated[idx - 1] |= 1;

            }

            if (ret == AVERROR(EAGAIN)) {

                ret = 0;

                idx--;

                continue;

            } else if (ret < 0)

                goto finish;

            /* send it to the next filter down the chain or to the muxer */

            if (idx < ost->nb_bitstream_filters) {

                /* HACK/FIXME! - See above */

                if (!(ost->bsf_extradata_updated[idx] & 2)) {

                    ret = avcodec_parameters_copy(ost->bsf_ctx[idx]->par_out, ost->bsf_ctx[idx - 1]->par_out);

                    if (ret < 0)

                        goto finish;

                    ost->bsf_extradata_updated[idx] |= 2;

                }

                ret = av_bsf_send_packet(ost->bsf_ctx[idx], pkt);

                if (ret < 0)

                    goto finish;

                idx++;

            } else

                write_packet(of, pkt, ost);

        }

    } else

        write_packet(of, pkt, ost);

finish:

    if (ret < 0 && ret != AVERROR_EOF) {

        av_log(NULL, AV_LOG_ERROR, "Error applying bitstream filters to an output "

               "packet for stream #%d:%d.\n", ost->file_index, ost->index);

        if(exit_on_error)

            exit_program(1);

    }

}


static void audio_pp_nb_voices (const char *typ, int nb)

{

    switch (nb) {

    case 0:

        printf ("Does not support %s\n", typ);

        break;

    case 1:

        printf ("One %s voice\n", typ);

        break;

    case INT_MAX:

        printf ("Theoretically supports many %s voices\n", typ);

        break;

    default:

        printf ("Theoretically supports upto %d %s voices\n", nb, typ);

        break;

    }

}