int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s)

{

    char buf1[32], tuple_type[32];

    int h, w, depth, maxval;

    pnm_get(s, buf1, sizeof(buf1));

    s->type= buf1[1]-'0';

    if(buf1[0] != 'P')

        return AVERROR_INVALIDDATA;

    if (s->type==1 || s->type==4) {

        avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;

    } else if (s->type==2 || s->type==5) {

        if (avctx->codec_id == AV_CODEC_ID_PGMYUV)

            avctx->pix_fmt = AV_PIX_FMT_YUV420P;

        else

            avctx->pix_fmt = AV_PIX_FMT_GRAY8;

    } else if (s->type==3 || s->type==6) {

        avctx->pix_fmt = AV_PIX_FMT_RGB24;

    } else if (s->type==7) {

        w      = -1;

        h      = -1;

        maxval = -1;

        depth  = -1;

        tuple_type[0] = '\0';

        for (;;) {

            pnm_get(s, buf1, sizeof(buf1));

            if (!strcmp(buf1, "WIDTH")) {

                pnm_get(s, buf1, sizeof(buf1));

                w = strtol(buf1, NULL, 10);

            } else if (!strcmp(buf1, "HEIGHT")) {

                pnm_get(s, buf1, sizeof(buf1));

                h = strtol(buf1, NULL, 10);

            } else if (!strcmp(buf1, "DEPTH")) {

                pnm_get(s, buf1, sizeof(buf1));

                depth = strtol(buf1, NULL, 10);

            } else if (!strcmp(buf1, "MAXVAL")) {

                pnm_get(s, buf1, sizeof(buf1));

                maxval = strtol(buf1, NULL, 10);

            } else if (!strcmp(buf1, "TUPLTYPE") ||

                       /* libavcodec used to write invalid files */

                       !strcmp(buf1, "TUPLETYPE")) {

                pnm_get(s, tuple_type, sizeof(tuple_type));

            } else if (!strcmp(buf1, "ENDHDR")) {

                break;

            } else {

                return AVERROR_INVALIDDATA;

            }

        }

        /* check that all tags are present */

        if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || av_image_check_size(w, h, 0, avctx) || s->bytestream >= s->bytestream_end)

            return AVERROR_INVALIDDATA;

        avctx->width  = w;

        avctx->height = h;

        s->maxval     = maxval;

        if (depth == 1) {

            if (maxval == 1) {

                avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;

            } else if (maxval < 256) {

                avctx->pix_fmt = AV_PIX_FMT_GRAY8;

            } else {

                avctx->pix_fmt = AV_PIX_FMT_GRAY16;

            }

        } else if (depth == 2) {

            if (maxval == 255)

                avctx->pix_fmt = AV_PIX_FMT_GRAY8A;

        } else if (depth == 3) {

            if (maxval < 256) {

                avctx->pix_fmt = AV_PIX_FMT_RGB24;

            } else {

                avctx->pix_fmt = AV_PIX_FMT_RGB48;

            }

        } else if (depth == 4) {

            if (maxval < 256) {

                avctx->pix_fmt = AV_PIX_FMT_RGBA;

            } else {

                avctx->pix_fmt = AV_PIX_FMT_RGBA64;

            }

        } else {

            return AVERROR_INVALIDDATA;

        }

        return 0;

    } else {

        return AVERROR_INVALIDDATA;

    }

    pnm_get(s, buf1, sizeof(buf1));

    w = atoi(buf1);

    pnm_get(s, buf1, sizeof(buf1));

    h = atoi(buf1);

    if(w <= 0 || h <= 0 || av_image_check_size(w, h, 0, avctx) || s->bytestream >= s->bytestream_end)

        return AVERROR_INVALIDDATA;

    avctx->width  = w;

    avctx->height = h;

    if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE && avctx->pix_fmt != AV_PIX_FMT_MONOBLACK) {

        pnm_get(s, buf1, sizeof(buf1));

        s->maxval = atoi(buf1);

        if (s->maxval <= 0) {

            av_log(avctx, AV_LOG_ERROR, "Invalid maxval: %d\n", s->maxval);

            s->maxval = 255;

        }

        if (s->maxval >= 256) {

            if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) {

                avctx->pix_fmt = AV_PIX_FMT_GRAY16;

            } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {

                avctx->pix_fmt = AV_PIX_FMT_RGB48;

            } else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P && s->maxval < 65536) {

                if (s->maxval < 512)

                    avctx->pix_fmt = AV_PIX_FMT_YUV420P9;

                else if (s->maxval < 1024)

                    avctx->pix_fmt = AV_PIX_FMT_YUV420P10;

                else

                    avctx->pix_fmt = AV_PIX_FMT_YUV420P16;

            } else {

                av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format\n");

                avctx->pix_fmt = AV_PIX_FMT_NONE;

                return AVERROR_INVALIDDATA;

            }

        }

    }else

        s->maxval=1;

    /* more check if YUV420 */

    if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_PLANAR) {

        if ((avctx->width & 1) != 0)

            return AVERROR_INVALIDDATA;

        h = (avctx->height * 2);

        if ((h % 3) != 0)

            return AVERROR_INVALIDDATA;

        h /= 3;

        avctx->height = h;

    }

    return 0;

}


static int usb_host_handle_data(USBDevice *dev, USBPacket *p)

{

    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);

    struct usbdevfs_urb *urb;

    AsyncURB *aurb;

    int ret, rem, prem, v;

    uint8_t *pbuf;

    uint8_t ep;

    trace_usb_host_req_data(s->bus_num, s->addr,

                            p->pid == USB_TOKEN_IN,

                            p->devep, p->iov.size);

    if (!is_valid(s, p->pid, p->devep)) {

        trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK);

        return USB_RET_NAK;

    }

    if (p->pid == USB_TOKEN_IN) {

        ep = p->devep | 0x80;

    } else {

        ep = p->devep;

    }

    if (is_halted(s, p->pid, p->devep)) {

        unsigned int arg = ep;

        ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &arg);

        if (ret < 0) {

            perror("USBDEVFS_CLEAR_HALT");

            trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK);

            return USB_RET_NAK;

        }

        clear_halt(s, p->pid, p->devep);

    }

    if (is_isoc(s, p->pid, p->devep)) {

        return usb_host_handle_iso_data(s, p, p->pid == USB_TOKEN_IN);

    }

    v = 0;

    prem = p->iov.iov[v].iov_len;

    pbuf = p->iov.iov[v].iov_base;

    rem = p->iov.size;

    while (rem) {

        if (prem == 0) {

            v++;

            assert(v < p->iov.niov);

            prem = p->iov.iov[v].iov_len;

            pbuf = p->iov.iov[v].iov_base;

            assert(prem <= rem);

        }

        aurb = async_alloc(s);

        aurb->packet = p;

        urb = &aurb->urb;

        urb->endpoint      = ep;

        urb->type          = usb_host_usbfs_type(s, p);

        urb->usercontext   = s;

        urb->buffer        = pbuf;

        urb->buffer_length = prem;

        if (urb->buffer_length > MAX_USBFS_BUFFER_SIZE) {

            urb->buffer_length = MAX_USBFS_BUFFER_SIZE;

        }

        pbuf += urb->buffer_length;

        prem -= urb->buffer_length;

        rem  -= urb->buffer_length;

        if (rem) {

            aurb->more         = 1;

        }

        trace_usb_host_urb_submit(s->bus_num, s->addr, aurb,

                                  urb->buffer_length, aurb->more);

        ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);

        DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n",

                urb->endpoint, urb->buffer_length, aurb->more, p, aurb);

        if (ret < 0) {

            perror("USBDEVFS_SUBMITURB");

            async_free(aurb);

            switch(errno) {

            case ETIMEDOUT:

                trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK);

                return USB_RET_NAK;

            case EPIPE:

            default:

                trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_STALL);

                return USB_RET_STALL;

            }

        }

    }

    return USB_RET_ASYNC;

}


static void checkpoint(void) {

    assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);

    check1(vvv);

    check2(vvv);

    assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));

#if 0

    if (((direntry_t*)vvv->directory.pointer)[1].attributes != 0xf)

        fprintf(stderr, "Nonono!\n");

    mapping_t* mapping;

    direntry_t* direntry;

    assert(vvv->mapping.size >= vvv->mapping.item_size * vvv->mapping.next);

    assert(vvv->directory.size >= vvv->directory.item_size * vvv->directory.next);

    if (vvv->mapping.next<47)

        return;

    assert((mapping = array_get(&(vvv->mapping), 47)));

    assert(mapping->dir_index < vvv->directory.next);

    direntry = array_get(&(vvv->directory), mapping->dir_index);

    assert(!memcmp(direntry->name, "USB     H  ", 11) || direntry->name[0]==0);

#endif

}


static void spapr_hotplug_set_signalled(uint32_t drc_index)

{

    sPAPRDRConnector *drc = spapr_drc_by_index(drc_index);

    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);

    drck->set_signalled(drc);

}


static uint32_t apic_mem_readb(void *opaque, target_phys_addr_t addr)

{

    return 0;

}


int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)

{

    BlockDriver *drv = bs->drv;

    if (!drv) {

        return -ENOMEDIUM;

    }

    if (drv->bdrv_get_allocated_file_size) {

        return drv->bdrv_get_allocated_file_size(bs);

    }

    if (bs->file) {

        return bdrv_get_allocated_file_size(bs->file);

    }

    return -ENOTSUP;

}


static uint64_t pxa2xx_fir_read(void *opaque, hwaddr addr,

                                unsigned size)

{

    PXA2xxFIrState *s = (PXA2xxFIrState *) opaque;

    uint8_t ret;

    switch (addr) {

    case ICCR0:

        return s->control[0];

    case ICCR1:

        return s->control[1];

    case ICCR2:

        return s->control[2];

    case ICDR:

        s->status[0] &= ~0x01;

        s->status[1] &= ~0x72;

        if (s->rx_len) {

            s->rx_len --;

            ret = s->rx_fifo[s->rx_start ++];

            s->rx_start &= 63;

            pxa2xx_fir_update(s);

            return ret;

        }

        printf("%s: Rx FIFO underrun.\n", __FUNCTION__);

        break;

    case ICSR0:

        return s->status[0];

    case ICSR1:

        return s->status[1] | (1 << 3);			/* TNF */

    case ICFOR:

        return s->rx_len;

    default:

        printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);

        break;

    }

    return 0;

}


static char *addr_to_string(const char *format,

                            struct sockaddr_storage *sa,

                            socklen_t salen) {

    char *addr;

    char host[NI_MAXHOST];

    char serv[NI_MAXSERV];

    int err;

    if ((err = getnameinfo((struct sockaddr *)sa, salen,

                           host, sizeof(host),

                           serv, sizeof(serv),

                           NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {

        VNC_DEBUG("Cannot resolve address %d: %s\n",

                  err, gai_strerror(err));

        return NULL;

    }

    if (asprintf(&addr, format, host, serv) < 0)

        return NULL;

    return addr;

}


static void sys_write(void *opaque, target_phys_addr_t addr,

                      uint64_t value, unsigned size)

{

    LM32SysState *s = opaque;

    char *testname;

    trace_lm32_sys_memory_write(addr, value);

    addr >>= 2;

    switch (addr) {

    case R_CTRL:

        qemu_system_shutdown_request();

        break;

    case R_PASSFAIL:

        s->regs[addr] = value;

        testname = (char *)s->testname;

        qemu_log("TC  %-16s %s\n", testname, (value) ? "FAILED" : "OK");

        break;

    case R_TESTNAME:

        s->regs[addr] = value;

        copy_testname(s);

        break;

    default:

        error_report("lm32_sys: write access to unknown register 0x"

                TARGET_FMT_plx, addr << 2);

        break;

    }

}


int bdrv_dirty_bitmap_get_meta(BlockDriverState *bs,

                               BdrvDirtyBitmap *bitmap, int64_t sector,

                               int nb_sectors)

{

    uint64_t i;

    int sectors_per_bit = 1 << hbitmap_granularity(bitmap->meta);

    /* To optimize: we can make hbitmap to internally check the range in a

     * coarse level, or at least do it word by word. */

    for (i = sector; i < sector + nb_sectors; i += sectors_per_bit) {

        if (hbitmap_get(bitmap->meta, i)) {

            return true;

        }

    }

    return false;

}


void vring_disable_notification(VirtIODevice *vdev, Vring *vring)

{

    if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {

        vring_set_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY);

    }

}


static abi_long do_accept(int fd, abi_ulong target_addr,

                          abi_ulong target_addrlen_addr)

{

    socklen_t addrlen;

    void *addr;

    abi_long ret;

    if (get_user_u32(addrlen, target_addrlen_addr))

        return -TARGET_EFAULT;

    if (addrlen < 0)

        return -TARGET_EINVAL;

    addr = alloca(addrlen);

    ret = get_errno(accept(fd, addr, &addrlen));

    if (!is_error(ret)) {

        host_to_target_sockaddr(target_addr, addr, addrlen);

        if (put_user_u32(addrlen, target_addrlen_addr))

            ret = -TARGET_EFAULT;

    }

    return ret;

}


static void mirror_write_complete(void *opaque, int ret)

{

    MirrorOp *op = opaque;

    MirrorBlockJob *s = op->s;

    if (ret < 0) {

        BlockDriverState *source = s->common.bs;

        BlockErrorAction action;

        bdrv_set_dirty(source, op->sector_num, op->nb_sectors);

        action = mirror_error_action(s, false, -ret);

        if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) {

            s->ret = ret;

        }

    }

    mirror_iteration_done(op, ret);

}


void shpc_cleanup(PCIDevice *d, MemoryRegion *bar)

{

    SHPCDevice *shpc = d->shpc;

    d->cap_present &= ~QEMU_PCI_CAP_SHPC;

    memory_region_del_subregion(bar, &shpc->mmio);

    /* TODO: cleanup config space changes? */

    g_free(shpc->config);

    g_free(shpc->cmask);

    g_free(shpc->wmask);

    g_free(shpc->w1cmask);

    g_free(shpc);

}


void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci,

                                        QGuestAllocator *alloc, uint16_t entry)

{

    uint16_t vector;

    uint32_t control;

    void *addr;

    g_assert(d->pdev->msix_enabled);

    addr = d->pdev->msix_table + (entry * 16);

    g_assert_cmpint(entry, >=, 0);

    g_assert_cmpint(entry, <, qpci_msix_table_size(d->pdev));

    vqpci->msix_entry = entry;

    vqpci->msix_addr = guest_alloc(alloc, 4);

    qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_LOWER_ADDR,

                                                    vqpci->msix_addr & ~0UL);

    qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_UPPER_ADDR,

                                            (vqpci->msix_addr >> 32) & ~0UL);

    qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_DATA, vqpci->msix_data);

    control = qpci_io_readl(d->pdev, addr + PCI_MSIX_ENTRY_VECTOR_CTRL);

    qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_VECTOR_CTRL,

                                        control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);

    qvirtio_pci_queue_select(&d->vdev, vqpci->vq.index);

    qpci_io_writew(d->pdev, d->addr + VIRTIO_MSI_QUEUE_VECTOR, entry);

    vector = qpci_io_readw(d->pdev, d->addr + VIRTIO_MSI_QUEUE_VECTOR);

    g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR);

}


int kvm_log_start(target_phys_addr_t phys_addr, target_phys_addr_t end_addr)

{

        return kvm_dirty_pages_log_change(phys_addr, end_addr,

                                          KVM_MEM_LOG_DIRTY_PAGES,

                                          KVM_MEM_LOG_DIRTY_PAGES);

}


static uint64_t master_abort_mem_read(void *opaque, hwaddr addr, unsigned size)

{

   return -1ULL;

}


static av_cold int a64multi_encode_init(AVCodecContext *avctx)

{

    A64Context *c = avctx->priv_data;

    int a;

    av_lfg_init(&c->randctx, 1);

    if (avctx->global_quality < 1) {

        c->mc_lifetime = 4;

    } else {

        c->mc_lifetime = avctx->global_quality /= FF_QP2LAMBDA;

    }

    av_log(avctx, AV_LOG_INFO, "charset lifetime set to %d frame(s)\n", c->mc_lifetime);

    c->mc_frame_counter = 0;

    c->mc_use_5col      = avctx->codec->id == AV_CODEC_ID_A64_MULTI5;

    c->mc_pal_size      = 4 + c->mc_use_5col;

    /* precalc luma values for later use */

    for (a = 0; a < c->mc_pal_size; a++) {

        c->mc_luma_vals[a]=a64_palette[mc_colors[a]][0] * 0.30 +

                           a64_palette[mc_colors[a]][1] * 0.59 +

                           a64_palette[mc_colors[a]][2] * 0.11;

    }

    if (!(c->mc_meta_charset = av_malloc_array(c->mc_lifetime, 32000 * sizeof(int))) ||

       !(c->mc_best_cb       = av_malloc(CHARSET_CHARS * 32 * sizeof(int)))     ||

       !(c->mc_charmap       = av_mallocz_array(c->mc_lifetime, 1000 * sizeof(int))) ||

       !(c->mc_colram        = av_mallocz(CHARSET_CHARS * sizeof(uint8_t)))     ||

       !(c->mc_charset       = av_malloc(0x800 * (INTERLACED+1) * sizeof(uint8_t)))) {

        av_log(avctx, AV_LOG_ERROR, "Failed to allocate buffer memory.\n");

        return AVERROR(ENOMEM);

    }

    /* set up extradata */

    if (!(avctx->extradata = av_mallocz(8 * 4 + FF_INPUT_BUFFER_PADDING_SIZE))) {

        av_log(avctx, AV_LOG_ERROR, "Failed to allocate memory for extradata.\n");

        return AVERROR(ENOMEM);

    }

    avctx->extradata_size = 8 * 4;

    AV_WB32(avctx->extradata, c->mc_lifetime);

    AV_WB32(avctx->extradata + 16, INTERLACED);

    avctx->coded_frame = av_frame_alloc();

    if (!avctx->coded_frame) {

        a64multi_close_encoder(avctx);

        return AVERROR(ENOMEM);

    }

    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;

    avctx->coded_frame->key_frame = 1;

    if (!avctx->codec_tag)

         avctx->codec_tag = AV_RL32("a64m");

    c->next_pts = AV_NOPTS_VALUE;

    return 0;

}


static int raw_decode(AVCodecContext *avctx,

                            void *data, int *data_size,

                            AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    int linesize_align = 4;

    RawVideoContext *context = avctx->priv_data;

    AVFrame * frame = (AVFrame *) data;

    AVPicture * picture = (AVPicture *) data;

    frame->pict_type        = avctx->coded_frame->pict_type;

    frame->interlaced_frame = avctx->coded_frame->interlaced_frame;

    frame->top_field_first = avctx->coded_frame->top_field_first;

    frame->reordered_opaque = avctx->reordered_opaque;

    frame->pkt_pts          = avctx->pkt->pts;

    frame->pkt_pos          = avctx->pkt->pos;

    if(context->tff>=0){

        frame->interlaced_frame = 1;

        frame->top_field_first  = context->tff;

    }

    //2bpp and 4bpp raw in avi and mov (yes this is ugly ...)

    if (context->buffer) {

        int i;

        uint8_t *dst = context->buffer;

        buf_size = context->length - 256*4;

        if (avctx->bits_per_coded_sample == 4){

            for(i=0; 2*i+1 < buf_size; i++){

                dst[2*i+0]= buf[i]>>4;

                dst[2*i+1]= buf[i]&15;

            }

            linesize_align = 8;

        } else {

            for(i=0; 4*i+3 < buf_size; i++){

                dst[4*i+0]= buf[i]>>6;

                dst[4*i+1]= buf[i]>>4&3;

                dst[4*i+2]= buf[i]>>2&3;

                dst[4*i+3]= buf[i]   &3;

            }

            linesize_align = 16;

        }

        buf= dst;

    }

    if(avctx->codec_tag == MKTAG('A', 'V', '1', 'x') ||

       avctx->codec_tag == MKTAG('A', 'V', 'u', 'p'))

        buf += buf_size - context->length;

    if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0))

        return -1;

    avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height);

    if((avctx->pix_fmt==PIX_FMT_PAL8 && buf_size < context->length) ||

       (av_pix_fmt_descriptors[avctx->pix_fmt].flags & PIX_FMT_PSEUDOPAL)) {

        frame->data[1]= context->palette;

    }

    if (avctx->pix_fmt == PIX_FMT_PAL8) {

        const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);

        if (pal) {

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

            frame->palette_has_changed = 1;

        }

    }

    if((avctx->pix_fmt==PIX_FMT_BGR24    ||

        avctx->pix_fmt==PIX_FMT_GRAY8    ||

        avctx->pix_fmt==PIX_FMT_RGB555LE ||

        avctx->pix_fmt==PIX_FMT_RGB555BE ||

        avctx->pix_fmt==PIX_FMT_RGB565LE ||

        avctx->pix_fmt==PIX_FMT_MONOWHITE ||

        avctx->pix_fmt==PIX_FMT_PAL8) &&

        FFALIGN(frame->linesize[0], linesize_align)*avctx->height <= buf_size)

        frame->linesize[0] = FFALIGN(frame->linesize[0], linesize_align);

    if(context->flip)

        flip(avctx, picture);

    if (   avctx->codec_tag == MKTAG('Y', 'V', '1', '2')

        || avctx->codec_tag == MKTAG('Y', 'V', '1', '6')

        || avctx->codec_tag == MKTAG('Y', 'V', '2', '4')

        || avctx->codec_tag == MKTAG('Y', 'V', 'U', '9'))

        FFSWAP(uint8_t *, picture->data[1], picture->data[2]);

    if(avctx->codec_tag == AV_RL32("yuv2") &&

       avctx->pix_fmt   == PIX_FMT_YUYV422) {

        int x, y;

        uint8_t *line = picture->data[0];

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

            for(x = 0; x < avctx->width; x++)

                line[2*x + 1] ^= 0x80;

            line += picture->linesize[0];

        }

    }

    *data_size = sizeof(AVPicture);

    return buf_size;

}


static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,

                             int is_chroma)

{

    int blk;

    int i, j, bx, by;

    uint8_t *dst, *prev, *ref, *ref_start, *ref_end;

    int v, col[2];

    const uint8_t *scan;

    int xoff, yoff;

    LOCAL_ALIGNED_16(DCTELEM, block, [64]);

    LOCAL_ALIGNED_16(uint8_t, ublock, [64]);

    LOCAL_ALIGNED_16(int32_t, dctblock, [64]);

    int coordmap[64];

    const int stride = c->pic.linesize[plane_idx];

    int bw = is_chroma ? (c->avctx->width  + 15) >> 4 : (c->avctx->width  + 7) >> 3;

    int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3;

    int width = c->avctx->width >> is_chroma;

    init_lengths(c, FFMAX(width, 8), bw);

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

        read_bundle(gb, c, i);

    ref_start = c->last.data[plane_idx];

    ref_end   = c->last.data[plane_idx]

                + (bw - 1 + c->last.linesize[plane_idx] * (bh - 1)) * 8;

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

        coordmap[i] = (i & 7) + (i >> 3) * stride;

    for (by = 0; by < bh; by++) {

        if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES]) < 0)

            return -1;

        if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES]) < 0)

            return -1;

        if (read_colors(gb, &c->bundle[BINK_SRC_COLORS], c) < 0)

            return -1;

        if (read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN]) < 0)

            return -1;

        if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF]) < 0)

            return -1;

        if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF]) < 0)

            return -1;

        if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0) < 0)

            return -1;

        if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1) < 0)

            return -1;

        if (read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN]) < 0)

            return -1;

        if (by == bh)

            break;

        dst  = c->pic.data[plane_idx]  + 8*by*stride;

        prev = c->last.data[plane_idx] + 8*by*stride;

        for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) {

            blk = get_value(c, BINK_SRC_BLOCK_TYPES);

            // 16x16 block type on odd line means part of the already decoded block, so skip it

            if ((by & 1) && blk == SCALED_BLOCK) {

                bx++;

                dst  += 8;

                prev += 8;

                continue;

            }

            switch (blk) {

            case SKIP_BLOCK:

                c->dsp.put_pixels_tab[1][0](dst, prev, stride, 8);

                break;

            case SCALED_BLOCK:

                blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES);

                switch (blk) {

                case RUN_BLOCK:

                    scan = bink_patterns[get_bits(gb, 4)];

                    i = 0;

                    do {

                        int run = get_value(c, BINK_SRC_RUN) + 1;

                        i += run;

                        if (i > 64) {

                            av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");

                            return -1;

                        }

                        if (get_bits1(gb)) {

                            v = get_value(c, BINK_SRC_COLORS);

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

                                ublock[*scan++] = v;

                        } else {

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

                                ublock[*scan++] = get_value(c, BINK_SRC_COLORS);

                        }

                    } while (i < 63);

                    if (i == 63)

                        ublock[*scan++] = get_value(c, BINK_SRC_COLORS);

                    break;

                case INTRA_BLOCK:

                    memset(dctblock, 0, sizeof(*dctblock) * 64);

                    dctblock[0] = get_value(c, BINK_SRC_INTRA_DC);

                    read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1);

                    c->bdsp.idct_put(ublock, 8, dctblock);

                    break;

                case FILL_BLOCK:

                    v = get_value(c, BINK_SRC_COLORS);

                    c->dsp.fill_block_tab[0](dst, v, stride, 16);

                    break;

                case PATTERN_BLOCK:

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

                        col[i] = get_value(c, BINK_SRC_COLORS);

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

                        v = get_value(c, BINK_SRC_PATTERN);

                        for (i = 0; i < 8; i++, v >>= 1)

                            ublock[i + j*8] = col[v & 1];

                    }

                    break;

                case RAW_BLOCK:

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

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

                            ublock[i + j*8] = get_value(c, BINK_SRC_COLORS);

                    break;

                default:

                    av_log(c->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk);

                    return -1;

                }

                if (blk != FILL_BLOCK)

                c->bdsp.scale_block(ublock, dst, stride);

                bx++;

                dst  += 8;

                prev += 8;

                break;

            case MOTION_BLOCK:

                xoff = get_value(c, BINK_SRC_X_OFF);

                yoff = get_value(c, BINK_SRC_Y_OFF);

                ref = prev + xoff + yoff * stride;

                if (ref < ref_start || ref > ref_end) {

                    av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",

                           bx*8 + xoff, by*8 + yoff);

                    return -1;

                }

                c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);

                break;

            case RUN_BLOCK:

                scan = bink_patterns[get_bits(gb, 4)];

                i = 0;

                do {

                    int run = get_value(c, BINK_SRC_RUN) + 1;

                    i += run;

                    if (i > 64) {

                        av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");

                        return -1;

                    }

                    if (get_bits1(gb)) {

                        v = get_value(c, BINK_SRC_COLORS);

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

                            dst[coordmap[*scan++]] = v;

                    } else {

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

                            dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS);

                    }

                } while (i < 63);

                if (i == 63)

                    dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS);

                break;

            case RESIDUE_BLOCK:

                xoff = get_value(c, BINK_SRC_X_OFF);

                yoff = get_value(c, BINK_SRC_Y_OFF);

                ref = prev + xoff + yoff * stride;

                if (ref < ref_start || ref > ref_end) {

                    av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",

                           bx*8 + xoff, by*8 + yoff);

                    return -1;

                }

                c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);

                c->dsp.clear_block(block);

                v = get_bits(gb, 7);

                read_residue(gb, block, v);

                c->dsp.add_pixels8(dst, block, stride);

                break;

            case INTRA_BLOCK:

                memset(dctblock, 0, sizeof(*dctblock) * 64);

                dctblock[0] = get_value(c, BINK_SRC_INTRA_DC);

                read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1);

                c->bdsp.idct_put(dst, stride, dctblock);

                break;

            case FILL_BLOCK:

                v = get_value(c, BINK_SRC_COLORS);

                c->dsp.fill_block_tab[1](dst, v, stride, 8);

                break;

            case INTER_BLOCK:

                xoff = get_value(c, BINK_SRC_X_OFF);

                yoff = get_value(c, BINK_SRC_Y_OFF);

                ref = prev + xoff + yoff * stride;

                c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);

                memset(dctblock, 0, sizeof(*dctblock) * 64);

                dctblock[0] = get_value(c, BINK_SRC_INTER_DC);

                read_dct_coeffs(gb, dctblock, bink_scan, bink_inter_quant, -1);

                c->bdsp.idct_add(dst, stride, dctblock);

                break;

            case PATTERN_BLOCK:

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

                    col[i] = get_value(c, BINK_SRC_COLORS);

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

                    v = get_value(c, BINK_SRC_PATTERN);

                    for (j = 0; j < 8; j++, v >>= 1)

                        dst[i*stride + j] = col[v & 1];

                }

                break;

            case RAW_BLOCK:

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

                    memcpy(dst + i*stride, c->bundle[BINK_SRC_COLORS].cur_ptr + i*8, 8);

                c->bundle[BINK_SRC_COLORS].cur_ptr += 64;

                break;

            default:

                av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk);

                return -1;

            }

        }

    }

    if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary

        skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F));

    return 0;

}


static void uart_write(void *opaque, hwaddr offset,

                          uint64_t value, unsigned size)

{

    CadenceUARTState *s = opaque;

    DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value);

    offset >>= 2;

    switch (offset) {

    case R_IER: /* ier (wts imr) */

        s->r[R_IMR] |= value;

        break;

    case R_IDR: /* idr (wtc imr) */

        s->r[R_IMR] &= ~value;

        break;

    case R_IMR: /* imr (read only) */

        break;

    case R_CISR: /* cisr (wtc) */

        s->r[R_CISR] &= ~value;

        break;

    case R_TX_RX: /* UARTDR */

        switch (s->r[R_MR] & UART_MR_CHMODE) {

        case NORMAL_MODE:

            uart_write_tx_fifo(s, (uint8_t *) &value, 1);

            break;

        case LOCAL_LOOPBACK:

            uart_write_rx_fifo(opaque, (uint8_t *) &value, 1);

            break;

        break;

    default:

        s->r[offset] = value;

    switch (offset) {

    case R_CR:

        uart_ctrl_update(s);

        break;

    case R_MR:

        uart_parameters_setup(s);

        break;

    uart_update_status(s);


static av_cold int flac_decode_init(AVCodecContext *avctx)

{

    FLACContext *s = avctx->priv_data;

    s->avctx = avctx;

    avctx->sample_fmt = SAMPLE_FMT_S16;

    if (avctx->extradata_size > 4) {

        /* initialize based on the demuxer-supplied streamdata header */

        if (avctx->extradata_size == FLAC_STREAMINFO_SIZE) {

            ff_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s,

                                     avctx->extradata);

            allocate_buffers(s);

        } else {

            init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size*8);

            metadata_parse(s);

        }

    }

    return 0;

}


static void m68020_cpu_initfn(Object *obj)

{

    M68kCPU *cpu = M68K_CPU(obj);

    CPUM68KState *env = &cpu->env;

    m68k_set_feature(env, M68K_FEATURE_M68000);

    m68k_set_feature(env, M68K_FEATURE_USP);

    m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);

    m68k_set_feature(env, M68K_FEATURE_QUAD_MULDIV);

    m68k_set_feature(env, M68K_FEATURE_BRAL);

    m68k_set_feature(env, M68K_FEATURE_BCCL);

    m68k_set_feature(env, M68K_FEATURE_BITFIELD);

    m68k_set_feature(env, M68K_FEATURE_EXT_FULL);

    m68k_set_feature(env, M68K_FEATURE_SCALED_INDEX);

    m68k_set_feature(env, M68K_FEATURE_LONG_MULDIV);

    m68k_set_feature(env, M68K_FEATURE_FPU);

    m68k_set_feature(env, M68K_FEATURE_CAS);

    m68k_set_feature(env, M68K_FEATURE_BKPT);

    m68k_set_feature(env, M68K_FEATURE_RTD);

}


static int add_shorts_metadata(int count, const char *name,

                               const char *sep, TiffContext *s)

{

    char *ap;

    int i;

    int16_t *sp;

    if (count >= INT_MAX / sizeof(int16_t) || count <= 0)

        return AVERROR_INVALIDDATA;

    if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int16_t))

        return AVERROR_INVALIDDATA;

    sp = av_malloc(count * sizeof(int16_t));

    if (!sp)

        return AVERROR(ENOMEM);

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

        sp[i] = tget_short(&s->gb, s->le);

    ap = shorts2str(sp, count, sep);

    av_freep(&sp);

    if (!ap)

        return AVERROR(ENOMEM);

    av_dict_set(avpriv_frame_get_metadatap(&s->picture), name, ap, AV_DICT_DONT_STRDUP_VAL);

    return 0;

}


static inline void RENAME(yuv2rgbX)(int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,

				    int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,

			    uint8_t *dest, int dstW, int dstbpp, int16_t * lumMmxFilter, int16_t * chrMmxFilter)

{

	if(fullUVIpol)

	{

//FIXME

	}//FULL_UV_IPOL

	else

	{

#ifdef HAVE_MMX

		if(dstbpp == 32) //FIXME untested

		{

			asm volatile(

				YSCALEYUV2RGBX

				WRITEBGR32

			:: "m" (-lumFilterSize), "m" (-chrFilterSize),

			   "m" (lumMmxFilter+lumFilterSize*4), "m" (chrMmxFilter+chrFilterSize*4),

			   "r" (dest), "m" (dstW),

			   "m" (lumSrc+lumFilterSize), "m" (chrSrc+chrFilterSize)

			: "%eax", "%ebx", "%ecx", "%edx", "%esi"

			);

		}

		else if(dstbpp==24) //FIXME untested

		{

			asm volatile(

				YSCALEYUV2RGBX

				"leal (%%eax, %%eax, 2), %%ebx	\n\t" //FIXME optimize

				"addl %4, %%ebx			\n\t"

				WRITEBGR24

			:: "m" (-lumFilterSize), "m" (-chrFilterSize),

			   "m" (lumMmxFilter+lumFilterSize*4), "m" (chrMmxFilter+chrFilterSize*4),

			   "r" (dest), "m" (dstW),

			   "m" (lumSrc+lumFilterSize), "m" (chrSrc+chrFilterSize)

			: "%eax", "%ebx", "%ecx", "%edx", "%esi"

			);

		}

		else if(dstbpp==15)

		{

			asm volatile(

				YSCALEYUV2RGBX

		/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

#ifdef DITHER1XBPP

				"paddusb b5Dither, %%mm2	\n\t"

				"paddusb g5Dither, %%mm4	\n\t"

				"paddusb r5Dither, %%mm5	\n\t"

#endif

				WRITEBGR15

			:: "m" (-lumFilterSize), "m" (-chrFilterSize),

			   "m" (lumMmxFilter+lumFilterSize*4), "m" (chrMmxFilter+chrFilterSize*4),

			   "r" (dest), "m" (dstW),

			   "m" (lumSrc+lumFilterSize), "m" (chrSrc+chrFilterSize)

			: "%eax", "%ebx", "%ecx", "%edx", "%esi"

			);

		}

		else if(dstbpp==16)

		{

			asm volatile(

				YSCALEYUV2RGBX

		/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

#ifdef DITHER1XBPP

				"paddusb b5Dither, %%mm2	\n\t"

				"paddusb g6Dither, %%mm4	\n\t"

				"paddusb r5Dither, %%mm5	\n\t"

#endif

				WRITEBGR16

			:: "m" (-lumFilterSize), "m" (-chrFilterSize),

			   "m" (lumMmxFilter+lumFilterSize*4), "m" (chrMmxFilter+chrFilterSize*4),

			   "r" (dest), "m" (dstW),

			   "m" (lumSrc+lumFilterSize), "m" (chrSrc+chrFilterSize)

			: "%eax", "%ebx", "%ecx", "%edx", "%esi"

			);

		}

#else

		if(dstbpp==32)

		{

			int i;

			for(i=0; i<(dstW>>1); i++){

				int j;

				int Y1=0;

				int Y2=0;

				int U=0;

				int V=0;

				int Cb, Cr, Cg;

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

				{

					Y1 += lumSrc[j][2*i] * lumFilter[j];

					Y2 += lumSrc[j][2*i+1] * lumFilter[j];

				}

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

				{

					U += chrSrc[j][i] * chrFilter[j];

					V += chrSrc[j][i+2048] * chrFilter[j];

				}

				Y1= clip_yuvtab_2568[ (Y1>>19) + 256 ];

				Y2= clip_yuvtab_2568[ (Y2>>19) + 256 ];

				U >>= 19;

				V >>= 19;

				Cb= clip_yuvtab_40cf[U+ 256];

				Cg= clip_yuvtab_1a1e[V+ 256] + yuvtab_0c92[U+ 256];

				Cr= clip_yuvtab_3343[V+ 256];

				dest[8*i+0]=clip_table[((Y1 + Cb) >>13)];

				dest[8*i+1]=clip_table[((Y1 + Cg) >>13)];

				dest[8*i+2]=clip_table[((Y1 + Cr) >>13)];

				dest[8*i+4]=clip_table[((Y2 + Cb) >>13)];

				dest[8*i+5]=clip_table[((Y2 + Cg) >>13)];

				dest[8*i+6]=clip_table[((Y2 + Cr) >>13)];

			}

		}

		else if(dstbpp==24)

		{

			int i;

			for(i=0; i<(dstW>>1); i++){

				int j;

				int Y1=0;

				int Y2=0;

				int U=0;

				int V=0;

				int Cb, Cr, Cg;

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

				{

					Y1 += lumSrc[j][2*i] * lumFilter[j];

					Y2 += lumSrc[j][2*i+1] * lumFilter[j];

				}

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

				{

					U += chrSrc[j][i] * chrFilter[j];

					V += chrSrc[j][i+2048] * chrFilter[j];

				}

				Y1= clip_yuvtab_2568[ (Y1>>19) + 256 ];

				Y2= clip_yuvtab_2568[ (Y2>>19) + 256 ];

				U >>= 19;

				V >>= 19;

				Cb= clip_yuvtab_40cf[U+ 256];

				Cg= clip_yuvtab_1a1e[V+ 256] + yuvtab_0c92[U+ 256];

				Cr= clip_yuvtab_3343[V+ 256];

				dest[0]=clip_table[((Y1 + Cb) >>13)];

				dest[1]=clip_table[((Y1 + Cg) >>13)];

				dest[2]=clip_table[((Y1 + Cr) >>13)];

				dest[3]=clip_table[((Y2 + Cb) >>13)];

				dest[4]=clip_table[((Y2 + Cg) >>13)];

				dest[5]=clip_table[((Y2 + Cr) >>13)];

				dest+=6;

			}

		}

		else if(dstbpp==16)

		{

			int i;

			for(i=0; i<(dstW>>1); i++){

				int j;

				int Y1=0;

				int Y2=0;

				int U=0;

				int V=0;

				int Cb, Cr, Cg;

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

				{

					Y1 += lumSrc[j][2*i] * lumFilter[j];

					Y2 += lumSrc[j][2*i+1] * lumFilter[j];

				}

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

				{

					U += chrSrc[j][i] * chrFilter[j];

					V += chrSrc[j][i+2048] * chrFilter[j];

				}

				Y1= clip_yuvtab_2568[ (Y1>>19) + 256 ];

				Y2= clip_yuvtab_2568[ (Y2>>19) + 256 ];

				U >>= 19;

				V >>= 19;

				Cb= clip_yuvtab_40cf[U+ 256];

				Cg= clip_yuvtab_1a1e[V+ 256] + yuvtab_0c92[U+ 256];

				Cr= clip_yuvtab_3343[V+ 256];

				((uint16_t*)dest)[2*i] =

					clip_table16b[(Y1 + Cb) >>13] |

					clip_table16g[(Y1 + Cg) >>13] |

					clip_table16r[(Y1 + Cr) >>13];

				((uint16_t*)dest)[2*i+1] =

					clip_table16b[(Y2 + Cb) >>13] |

					clip_table16g[(Y2 + Cg) >>13] |

					clip_table16r[(Y2 + Cr) >>13];

			}

		}

		else if(dstbpp==15)

		{

			int i;

			for(i=0; i<(dstW>>1); i++){

				int j;

				int Y1=0;

				int Y2=0;

				int U=0;

				int V=0;

				int Cb, Cr, Cg;

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

				{

					Y1 += lumSrc[j][2*i] * lumFilter[j];

					Y2 += lumSrc[j][2*i+1] * lumFilter[j];

				}

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

				{

					U += chrSrc[j][i] * chrFilter[j];

					V += chrSrc[j][i+2048] * chrFilter[j];

				}

				Y1= clip_yuvtab_2568[ (Y1>>19) + 256 ];

				Y2= clip_yuvtab_2568[ (Y2>>19) + 256 ];

				U >>= 19;

				V >>= 19;

				Cb= clip_yuvtab_40cf[U+ 256];

				Cg= clip_yuvtab_1a1e[V+ 256] + yuvtab_0c92[U+ 256];

				Cr= clip_yuvtab_3343[V+ 256];

				((uint16_t*)dest)[2*i] =

					clip_table15b[(Y1 + Cb) >>13] |

					clip_table15g[(Y1 + Cg) >>13] |

					clip_table15r[(Y1 + Cr) >>13];

				((uint16_t*)dest)[2*i+1] =

					clip_table15b[(Y2 + Cb) >>13] |

					clip_table15g[(Y2 + Cg) >>13] |

					clip_table15r[(Y2 + Cr) >>13];

			}

		}

#endif

	} //!FULL_UV_IPOL

}


static int opt_map(OptionsContext *o, const char *opt, const char *arg)

{

    StreamMap *m = NULL;

    int i, negative = 0, file_idx;

    int sync_file_idx = -1, sync_stream_idx;

    char *p, *sync;

    char *map;

    if (*arg == '-') {

        negative = 1;

        arg++;

    }

    map = av_strdup(arg);

    /* parse sync stream first, just pick first matching stream */

    if (sync = strchr(map, ',')) {

        *sync = 0;

        sync_file_idx = strtol(sync + 1, &sync, 0);

        if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {

            av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx);

            exit_program(1);

        }

        if (*sync)

            sync++;

        for (i = 0; i < input_files[sync_file_idx].nb_streams; i++)

            if (check_stream_specifier(input_files[sync_file_idx].ctx,

                                       input_files[sync_file_idx].ctx->streams[i], sync) == 1) {

                sync_stream_idx = i;

                break;

            }

        if (i == input_files[sync_file_idx].nb_streams) {

            av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not "

                                       "match any streams.\n", arg);

            exit_program(1);

        }

    }

    file_idx = strtol(map, &p, 0);

    if (file_idx >= nb_input_files || file_idx < 0) {

        av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);

        exit_program(1);

    }

    if (negative)

        /* disable some already defined maps */

        for (i = 0; i < o->nb_stream_maps; i++) {

            m = &o->stream_maps[i];

            if (file_idx == m->file_index &&

                check_stream_specifier(input_files[m->file_index].ctx,

                                       input_files[m->file_index].ctx->streams[m->stream_index],

                                       *p == ':' ? p + 1 : p) > 0)

                m->disabled = 1;

        }

    else

        for (i = 0; i < input_files[file_idx].nb_streams; i++) {

            if (check_stream_specifier(input_files[file_idx].ctx, input_files[file_idx].ctx->streams[i],

                        *p == ':' ? p + 1 : p) <= 0)

                continue;

            o->stream_maps = grow_array(o->stream_maps, sizeof(*o->stream_maps),

                                        &o->nb_stream_maps, o->nb_stream_maps + 1);

            m = &o->stream_maps[o->nb_stream_maps - 1];

            m->file_index   = file_idx;

            m->stream_index = i;

            if (sync_file_idx >= 0) {

                m->sync_file_index   = sync_file_idx;

                m->sync_stream_index = sync_stream_idx;

            } else {

                m->sync_file_index   = file_idx;

                m->sync_stream_index = i;

            }

        }

    if (!m) {

        av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n", arg);

        exit_program(1);

    }

    av_freep(&map);

    return 0;

}


static void network_to_remote_block(RDMARemoteBlock *rb)

{

    rb->remote_host_addr = ntohll(rb->remote_host_addr);

    rb->offset = ntohll(rb->offset);

    rb->length = ntohll(rb->length);

    rb->remote_rkey = ntohl(rb->remote_rkey);

}


static uint8_t *advance_line(uint8_t *start, uint8_t *line,

                             int stride, int *y, int h, int interleave)

{

    *y += interleave;

    if (*y < h) {

        return line + interleave * stride;

    } else {

        *y = (*y + 1) & (interleave - 1);

        if (*y) {

            return start + *y * stride;

        } else {

            return NULL;

        }

    }

}


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

                                 ptrdiff_t stride)

{

    avc_luma_midh_qrt_16w_msa(src - (2 * stride) - 2,

                              stride, dst, stride, 16, 1);

}


void ff_cavs_init_top_lines(AVSContext *h) {

    /* alloc top line of predictors */

    h->top_qp       = av_malloc( h->mb_width);

    h->top_mv[0]    = av_malloc((h->mb_width*2+1)*sizeof(cavs_vector));

    h->top_mv[1]    = av_malloc((h->mb_width*2+1)*sizeof(cavs_vector));

    h->top_pred_Y   = av_malloc( h->mb_width*2*sizeof(*h->top_pred_Y));

    h->top_border_y = av_malloc((h->mb_width+1)*16);

    h->top_border_u = av_malloc( h->mb_width * 10);

    h->top_border_v = av_malloc( h->mb_width * 10);

    /* alloc space for co-located MVs and types */

    h->col_mv       = av_malloc( h->mb_width*h->mb_height*4*sizeof(cavs_vector));

    h->col_type_base = av_malloc(h->mb_width*h->mb_height);

    h->block        = av_mallocz(64*sizeof(int16_t));

}


int avresample_open(AVAudioResampleContext *avr)

{

    int ret;

    /* set channel mixing parameters */

    avr->in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout);

    if (avr->in_channels <= 0 || avr->in_channels > AVRESAMPLE_MAX_CHANNELS) {

        av_log(avr, AV_LOG_ERROR, "Invalid input channel layout: %"PRIu64"\n",

               avr->in_channel_layout);

        return AVERROR(EINVAL);

    }

    avr->out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout);

    if (avr->out_channels <= 0 || avr->out_channels > AVRESAMPLE_MAX_CHANNELS) {

        av_log(avr, AV_LOG_ERROR, "Invalid output channel layout: %"PRIu64"\n",

               avr->out_channel_layout);

        return AVERROR(EINVAL);

    }

    avr->resample_channels = FFMIN(avr->in_channels, avr->out_channels);

    avr->downmix_needed    = avr->in_channels  > avr->out_channels;

    avr->upmix_needed      = avr->out_channels > avr->in_channels ||

                             avr->am->matrix                      ||

                             (avr->out_channels == avr->in_channels &&

                              avr->in_channel_layout != avr->out_channel_layout);

    avr->mixing_needed     = avr->downmix_needed || avr->upmix_needed;

    /* set resampling parameters */

    avr->resample_needed   = avr->in_sample_rate != avr->out_sample_rate ||

                             avr->force_resampling;

    /* select internal sample format if not specified by the user */

    if (avr->internal_sample_fmt == AV_SAMPLE_FMT_NONE &&

        (avr->mixing_needed || avr->resample_needed)) {

        enum AVSampleFormat  in_fmt = av_get_planar_sample_fmt(avr->in_sample_fmt);

        enum AVSampleFormat out_fmt = av_get_planar_sample_fmt(avr->out_sample_fmt);

        int max_bps = FFMAX(av_get_bytes_per_sample(in_fmt),

                            av_get_bytes_per_sample(out_fmt));

        if (max_bps <= 2) {

            avr->internal_sample_fmt = AV_SAMPLE_FMT_S16P;

        } else if (avr->mixing_needed) {

            avr->internal_sample_fmt = AV_SAMPLE_FMT_FLTP;

        } else {

            if (max_bps <= 4) {

                if (in_fmt  == AV_SAMPLE_FMT_S32P ||

                    out_fmt == AV_SAMPLE_FMT_S32P) {

                    if (in_fmt  == AV_SAMPLE_FMT_FLTP ||

                        out_fmt == AV_SAMPLE_FMT_FLTP) {

                        /* if one is s32 and the other is flt, use dbl */

                        avr->internal_sample_fmt = AV_SAMPLE_FMT_DBLP;

                    } else {

                        /* if one is s32 and the other is s32, s16, or u8, use s32 */

                        avr->internal_sample_fmt = AV_SAMPLE_FMT_S32P;

                    }

                } else {

                    /* if one is flt and the other is flt, s16 or u8, use flt */

                    avr->internal_sample_fmt = AV_SAMPLE_FMT_FLTP;

                }

            } else {

                /* if either is dbl, use dbl */

                avr->internal_sample_fmt = AV_SAMPLE_FMT_DBLP;

            }

        }

        av_log(avr, AV_LOG_DEBUG, "Using %s as internal sample format\n",

               av_get_sample_fmt_name(avr->internal_sample_fmt));

    }

    /* set sample format conversion parameters */

    if (avr->in_channels == 1)

        avr->in_sample_fmt = av_get_planar_sample_fmt(avr->in_sample_fmt);

    if (avr->out_channels == 1)

        avr->out_sample_fmt = av_get_planar_sample_fmt(avr->out_sample_fmt);

    avr->in_convert_needed = (avr->resample_needed || avr->mixing_needed) &&

                              avr->in_sample_fmt != avr->internal_sample_fmt;

    if (avr->resample_needed || avr->mixing_needed)

        avr->out_convert_needed = avr->internal_sample_fmt != avr->out_sample_fmt;

    else

        avr->out_convert_needed = avr->in_sample_fmt != avr->out_sample_fmt;

    /* allocate buffers */

    if (avr->mixing_needed || avr->in_convert_needed) {

        avr->in_buffer = ff_audio_data_alloc(FFMAX(avr->in_channels, avr->out_channels),

                                             0, avr->internal_sample_fmt,

                                             "in_buffer");

        if (!avr->in_buffer) {

            ret = AVERROR(EINVAL);

            goto error;

        }

    }

    if (avr->resample_needed) {

        avr->resample_out_buffer = ff_audio_data_alloc(avr->out_channels,

                                                       0, avr->internal_sample_fmt,

                                                       "resample_out_buffer");

        if (!avr->resample_out_buffer) {

            ret = AVERROR(EINVAL);

            goto error;

        }

    }

    if (avr->out_convert_needed) {

        avr->out_buffer = ff_audio_data_alloc(avr->out_channels, 0,

                                              avr->out_sample_fmt, "out_buffer");

        if (!avr->out_buffer) {

            ret = AVERROR(EINVAL);

            goto error;

        }

    }

    avr->out_fifo = av_audio_fifo_alloc(avr->out_sample_fmt, avr->out_channels,

                                        1024);

    if (!avr->out_fifo) {

        ret = AVERROR(ENOMEM);

        goto error;

    }

    /* setup contexts */

    if (avr->in_convert_needed) {

        avr->ac_in = ff_audio_convert_alloc(avr, avr->internal_sample_fmt,

                                            avr->in_sample_fmt, avr->in_channels);

        if (!avr->ac_in) {

            ret = AVERROR(ENOMEM);

            goto error;

        }

    }

    if (avr->out_convert_needed) {

        enum AVSampleFormat src_fmt;

        if (avr->in_convert_needed)

            src_fmt = avr->internal_sample_fmt;

        else

            src_fmt = avr->in_sample_fmt;

        avr->ac_out = ff_audio_convert_alloc(avr, avr->out_sample_fmt, src_fmt,

                                             avr->out_channels);

        if (!avr->ac_out) {

            ret = AVERROR(ENOMEM);

            goto error;

        }

    }

    if (avr->resample_needed) {

        avr->resample = ff_audio_resample_init(avr);

        if (!avr->resample) {

            ret = AVERROR(ENOMEM);

            goto error;

        }

    }

    if (avr->mixing_needed) {

        ret = ff_audio_mix_init(avr);

        if (ret < 0)

            goto error;

    }

    return 0;

error:

    avresample_close(avr);

    return ret;

}


bool cpu_exec_all(void)

{

    int r;

    /* Account partial waits to the vm_clock.  */

    qemu_clock_warp(vm_clock);

    if (next_cpu == NULL) {

        next_cpu = first_cpu;

    }

    for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {

        CPUState *env = next_cpu;

        qemu_clock_enable(vm_clock,

                          (env->singlestep_enabled & SSTEP_NOTIMER) == 0);

#ifndef CONFIG_IOTHREAD

        if (qemu_alarm_pending()) {

            break;

        }

#endif

        if (cpu_can_run(env)) {

            if (kvm_enabled()) {

                r = kvm_cpu_exec(env);

                qemu_kvm_eat_signals(env);

            } else {

                r = tcg_cpu_exec(env);

            }

            if (r == EXCP_DEBUG) {

                cpu_handle_guest_debug(env);

                break;

            }

        } else if (env->stop || env->stopped) {

            break;

        }

    }

    exit_request = 0;

    return !all_cpu_threads_idle();

}


static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size,

                           uint32_t node, bool dedicated_hp_event_source,

                           Error **errp)

{

    sPAPRDRConnector *drc;

    sPAPRDRConnectorClass *drck;

    uint32_t nr_lmbs = size/SPAPR_MEMORY_BLOCK_SIZE;

    int i, fdt_offset, fdt_size;

    void *fdt;

    uint64_t addr = addr_start;

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

        drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_LMB,

                addr/SPAPR_MEMORY_BLOCK_SIZE);

        g_assert(drc);

        fdt = create_device_tree(&fdt_size);

        fdt_offset = spapr_populate_memory_node(fdt, node, addr,

                                                SPAPR_MEMORY_BLOCK_SIZE);

        drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);

        drck->attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, errp);

        addr += SPAPR_MEMORY_BLOCK_SIZE;

    /* send hotplug notification to the

     * guest only in case of hotplugged memory

     */

    if (dev->hotplugged) {

        if (dedicated_hp_event_source) {

            drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_LMB,

                    addr_start / SPAPR_MEMORY_BLOCK_SIZE);

            drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);

            spapr_hotplug_req_add_by_count_indexed(SPAPR_DR_CONNECTOR_TYPE_LMB,

                                                   nr_lmbs,

                                                   drck->get_index(drc));

        } else {

            spapr_hotplug_req_add_by_count(SPAPR_DR_CONNECTOR_TYPE_LMB,

                                           nr_lmbs);


CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip,

                        const unsigned int pci_irq_nrs[4], int do_init,

                        const char *cpu_model)

{

    target_phys_addr_t ram_bases[PPC440EP_SDRAM_NR_BANKS];

    target_phys_addr_t ram_sizes[PPC440EP_SDRAM_NR_BANKS];

    CPUState *env;

    qemu_irq *pic;

    qemu_irq *irqs;

    qemu_irq *pci_irqs;

    if (cpu_model == NULL)

        cpu_model = "405"; // XXX: should be 440EP

    env = cpu_init(cpu_model);

    if (!env) {

        fprintf(stderr, "Unable to initialize CPU!\n");

        exit(1);

    }

    ppc_dcr_init(env, NULL, NULL);

    /* interrupt controller */

    irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);

    irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];

    irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT];

    pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);

    /* SDRAM controller */

    memset(ram_bases, 0, sizeof(ram_bases));

    memset(ram_sizes, 0, sizeof(ram_sizes));

    *ram_size = ppc4xx_sdram_adjust(*ram_size, PPC440EP_SDRAM_NR_BANKS,

                                    ram_bases, ram_sizes,

                                    ppc440ep_sdram_bank_sizes);

    /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */

    ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_bases,

                      ram_sizes, do_init);

    /* PCI */

    pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);

    pci_irqs[0] = pic[pci_irq_nrs[0]];

    pci_irqs[1] = pic[pci_irq_nrs[1]];

    pci_irqs[2] = pic[pci_irq_nrs[2]];

    pci_irqs[3] = pic[pci_irq_nrs[3]];

    *pcip = ppc4xx_pci_init(env, pci_irqs,

                            PPC440EP_PCI_CONFIG,

                            PPC440EP_PCI_INTACK,

                            PPC440EP_PCI_SPECIAL,

                            PPC440EP_PCI_REGS);

    if (!*pcip)

        printf("couldn't create PCI controller!\n");

    isa_mmio_init(PPC440EP_PCI_IO, PPC440EP_PCI_IOLEN);

    if (serial_hds[0] != NULL) {

        serial_mm_init(0xef600300, 0, pic[0], PPC_SERIAL_MM_BAUDBASE,

                       serial_hds[0], 1, 1);

    }

    if (serial_hds[1] != NULL) {

        serial_mm_init(0xef600400, 0, pic[1], PPC_SERIAL_MM_BAUDBASE,

                       serial_hds[1], 1, 1);

    }

    return env;

}


int avpriv_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf,

                             int bufsize, int *header_size, int *coeff)

{

    int offset, cutoff;

    if (bufsize < 24)

        return AVERROR_INVALIDDATA;

    if (AV_RB16(buf) != 0x8000)

        return AVERROR_INVALIDDATA;

    offset = AV_RB16(buf + 2) + 4;

    /* if copyright string is within the provided data, validate it */

    if (bufsize >= offset && memcmp(buf + offset - 6, "(c)CRI", 6))

        return AVERROR_INVALIDDATA;

    /* check for encoding=3 block_size=18, sample_size=4 */

    if (buf[4] != 3 || buf[5] != 18 || buf[6] != 4) {

        av_log_ask_for_sample(avctx, "unsupported ADX format\n");

        return AVERROR_PATCHWELCOME;

    }

    /* channels */

    avctx->channels = buf[7];

    if (avctx->channels > 2)

        return AVERROR_INVALIDDATA;

    /* sample rate */

    avctx->sample_rate = AV_RB32(buf + 8);

    if (avctx->sample_rate < 1 ||

        avctx->sample_rate > INT_MAX / (avctx->channels * BLOCK_SIZE * 8))

        return AVERROR_INVALIDDATA;

    /* bit rate */

    avctx->bit_rate = avctx->sample_rate * avctx->channels * BLOCK_SIZE * 8 / BLOCK_SAMPLES;

    /* LPC coefficients */

    if (coeff) {

        cutoff = AV_RB16(buf + 16);

        ff_adx_calculate_coeffs(cutoff, avctx->sample_rate, COEFF_BITS, coeff);

    }

    *header_size = offset;

    return 0;

}


static int g2m_decode_frame(AVCodecContext *avctx, void *data,

                            int *got_picture_ptr, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    G2MContext *c = avctx->priv_data;

    AVFrame *pic = data;

    GetByteContext bc, tbc;

    int magic;

    int got_header = 0;

    uint32_t chunk_size, r_mask, g_mask, b_mask;

    int chunk_type, chunk_start;

    int i;

    int ret;

    if (buf_size < 12) {

        av_log(avctx, AV_LOG_ERROR,

               "Frame should have at least 12 bytes, got %d instead\n",

               buf_size);

        return AVERROR_INVALIDDATA;

    }

    bytestream2_init(&bc, buf, buf_size);

    magic = bytestream2_get_be32(&bc);

    if ((magic & ~0xF) != MKBETAG('G', '2', 'M', '0') ||

        (magic & 0xF) < 2 || (magic & 0xF) > 5) {

        av_log(avctx, AV_LOG_ERROR, "Wrong magic %08X\n", magic);

        return AVERROR_INVALIDDATA;

    }

    c->swapuv = magic == MKBETAG('G', '2', 'M', '2');

    while (bytestream2_get_bytes_left(&bc) > 5) {

        chunk_size  = bytestream2_get_le32(&bc) - 1;

        chunk_type  = bytestream2_get_byte(&bc);

        chunk_start = bytestream2_tell(&bc);

        if (chunk_size > bytestream2_get_bytes_left(&bc)) {

            av_log(avctx, AV_LOG_ERROR, "Invalid chunk size %"PRIu32" type %02X\n",

                   chunk_size, chunk_type);

            break;

        }

        switch (chunk_type) {

        case DISPLAY_INFO:

            got_header =

            c->got_header = 0;

            if (chunk_size < 21) {

                av_log(avctx, AV_LOG_ERROR, "Invalid display info size %"PRIu32"\n",

                       chunk_size);

                break;

            }

            c->width  = bytestream2_get_be32(&bc);

            c->height = bytestream2_get_be32(&bc);

            if (c->width  < 16 || c->width  > c->orig_width ||

                c->height < 16 || c->height > c->orig_height) {

                av_log(avctx, AV_LOG_ERROR,

                       "Invalid frame dimensions %dx%d\n",

                       c->width, c->height);

                ret = AVERROR_INVALIDDATA;

                goto header_fail;

            }

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

                ret = ff_set_dimensions(avctx, c->width, c->height);

                if (ret < 0)

                    goto header_fail;

            }

            c->compression = bytestream2_get_be32(&bc);

            if (c->compression != 2 && c->compression != 3) {

                av_log(avctx, AV_LOG_ERROR,

                       "Unknown compression method %d\n",

                       c->compression);

                ret = AVERROR_PATCHWELCOME;

                goto header_fail;

            }

            c->tile_width  = bytestream2_get_be32(&bc);

            c->tile_height = bytestream2_get_be32(&bc);

            if (c->tile_width <= 0 || c->tile_height <= 0 ||

                ((c->tile_width | c->tile_height) & 0xF) ||

                c->tile_width * 4LL * c->tile_height >= INT_MAX

            ) {

                av_log(avctx, AV_LOG_ERROR,

                       "Invalid tile dimensions %dx%d\n",

                       c->tile_width, c->tile_height);

                ret = AVERROR_INVALIDDATA;

                goto header_fail;

            }

            c->tiles_x = (c->width  + c->tile_width  - 1) / c->tile_width;

            c->tiles_y = (c->height + c->tile_height - 1) / c->tile_height;

            c->bpp     = bytestream2_get_byte(&bc);

            if (c->bpp == 32) {

                if (bytestream2_get_bytes_left(&bc) < 16 ||

                    (chunk_size - 21) < 16) {

                    av_log(avctx, AV_LOG_ERROR,

                           "Display info: missing bitmasks!\n");

                    ret = AVERROR_INVALIDDATA;

                    goto header_fail;

                }

                r_mask = bytestream2_get_be32(&bc);

                g_mask = bytestream2_get_be32(&bc);

                b_mask = bytestream2_get_be32(&bc);

                if (r_mask != 0xFF0000 || g_mask != 0xFF00 || b_mask != 0xFF) {

                    av_log(avctx, AV_LOG_ERROR,

                           "Invalid or unsupported bitmasks: R=%"PRIX32", G=%"PRIX32", B=%"PRIX32"\n",

                           r_mask, g_mask, b_mask);

                    ret = AVERROR_PATCHWELCOME;

                    goto header_fail;

                }

            } else {

                avpriv_request_sample(avctx, "bpp=%d", c->bpp);

                ret = AVERROR_PATCHWELCOME;

                goto header_fail;

            }

            if (g2m_init_buffers(c)) {

                ret = AVERROR(ENOMEM);

                goto header_fail;

            }

            got_header = 1;

            break;

        case TILE_DATA:

            if (!c->tiles_x || !c->tiles_y) {

                av_log(avctx, AV_LOG_WARNING,

                       "No display info - skipping tile\n");

                break;

            }

            if (chunk_size < 2) {

                av_log(avctx, AV_LOG_ERROR, "Invalid tile data size %"PRIu32"\n",

                       chunk_size);

                break;

            }

            c->tile_x = bytestream2_get_byte(&bc);

            c->tile_y = bytestream2_get_byte(&bc);

            if (c->tile_x >= c->tiles_x || c->tile_y >= c->tiles_y) {

                av_log(avctx, AV_LOG_ERROR,

                       "Invalid tile pos %d,%d (in %dx%d grid)\n",

                       c->tile_x, c->tile_y, c->tiles_x, c->tiles_y);

                break;

            }

            ret = 0;

            switch (c->compression) {

            case COMPR_EPIC_J_B:

                ret = epic_jb_decode_tile(c, c->tile_x, c->tile_y,

                                          buf + bytestream2_tell(&bc),

                                          chunk_size - 2, avctx);

                break;

            case COMPR_KEMPF_J_B:

                ret = kempf_decode_tile(c, c->tile_x, c->tile_y,

                                        buf + bytestream2_tell(&bc),

                                        chunk_size - 2);

                break;

            }

            if (ret && c->framebuf)

                av_log(avctx, AV_LOG_ERROR, "Error decoding tile %d,%d\n",

                       c->tile_x, c->tile_y);

            break;

        case CURSOR_POS:

            if (chunk_size < 5) {

                av_log(avctx, AV_LOG_ERROR, "Invalid cursor pos size %"PRIu32"\n",

                       chunk_size);

                break;

            }

            c->cursor_x = bytestream2_get_be16(&bc);

            c->cursor_y = bytestream2_get_be16(&bc);

            break;

        case CURSOR_SHAPE:

            if (chunk_size < 8) {

                av_log(avctx, AV_LOG_ERROR, "Invalid cursor data size %"PRIu32"\n",

                       chunk_size);

                break;

            }

            bytestream2_init(&tbc, buf + bytestream2_tell(&bc),

                             chunk_size - 4);

            g2m_load_cursor(avctx, c, &tbc);

            break;

        case CHUNK_CC:

        case CHUNK_CD:

            break;

        default:

            av_log(avctx, AV_LOG_WARNING, "Skipping chunk type %02d\n",

                   chunk_type);

        }

        /* navigate to next chunk */

        bytestream2_skip(&bc, chunk_start + chunk_size - bytestream2_tell(&bc));

    }

    if (got_header)

        c->got_header = 1;

    if (c->width && c->height && c->framebuf) {

        if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)

            return ret;

        pic->key_frame = got_header;

        pic->pict_type = got_header ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;

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

            memcpy(pic->data[0] + i * pic->linesize[0],

                   c->framebuf + i * c->framebuf_stride,

                   c->width * 3);

        g2m_paint_cursor(c, pic->data[0], pic->linesize[0]);

        *got_picture_ptr = 1;

    }

    return buf_size;

header_fail:

    c->width   =

    c->height  = 0;

    c->tiles_x =

    c->tiles_y = 0;

    return ret;

}


static int decode_slice(AVCodecContext *avctx,

                        const uint8_t  *buffer,

                        uint32_t        size)

{

    H264Context * const h = avctx->priv_data;

    MpegEncContext * const s = &h->s;

    VASliceParameterBufferH264 *slice_param;

    dprintf(avctx, "decode_slice(): buffer %p, size %d\n", buffer, size);

    /* Fill in VASliceParameterBufferH264. */

    slice_param = (VASliceParameterBufferH264 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size);

    if (!slice_param)

        return -1;

    slice_param->slice_data_bit_offset          = get_bits_count(&h->s.gb) + 8; /* bit buffer started beyond nal_unit_type */

    slice_param->first_mb_in_slice              = (s->mb_y >> FIELD_OR_MBAFF_PICTURE) * s->mb_width + s->mb_x;

    slice_param->slice_type                     = ff_h264_get_slice_type(h);

    slice_param->direct_spatial_mv_pred_flag    = h->slice_type == FF_B_TYPE ? h->direct_spatial_mv_pred : 0;

    slice_param->num_ref_idx_l0_active_minus1   = h->list_count > 0 ? h->ref_count[0] - 1 : 0;

    slice_param->num_ref_idx_l1_active_minus1   = h->list_count > 1 ? h->ref_count[1] - 1 : 0;

    slice_param->cabac_init_idc                 = h->cabac_init_idc;

    slice_param->slice_qp_delta                 = s->qscale - h->pps.init_qp;

    slice_param->disable_deblocking_filter_idc  = h->deblocking_filter < 2 ? !h->deblocking_filter : h->deblocking_filter;

    slice_param->slice_alpha_c0_offset_div2     = h->slice_alpha_c0_offset / 2;

    slice_param->slice_beta_offset_div2         = h->slice_beta_offset / 2;

    slice_param->luma_log2_weight_denom         = h->luma_log2_weight_denom;

    slice_param->chroma_log2_weight_denom       = h->chroma_log2_weight_denom;

    fill_vaapi_RefPicList(slice_param->RefPicList0, h->ref_list[0], h->list_count > 0 ? h->ref_count[0] : 0);

    fill_vaapi_RefPicList(slice_param->RefPicList1, h->ref_list[1], h->list_count > 1 ? h->ref_count[1] : 0);

    fill_vaapi_plain_pred_weight_table(h, 0,

                                       &slice_param->luma_weight_l0_flag,   slice_param->luma_weight_l0,   slice_param->luma_offset_l0,

                                       &slice_param->chroma_weight_l0_flag, slice_param->chroma_weight_l0, slice_param->chroma_offset_l0);

    fill_vaapi_plain_pred_weight_table(h, 1,

                                       &slice_param->luma_weight_l1_flag,   slice_param->luma_weight_l1,   slice_param->luma_offset_l1,

                                       &slice_param->chroma_weight_l1_flag, slice_param->chroma_weight_l1, slice_param->chroma_offset_l1);

    return 0;

}


static void apply_mdct(AC3EncodeContext *s)

{

    int blk, ch;

    for (ch = 0; ch < s->channels; ch++) {

        for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {

            AC3Block *block = &s->blocks[blk];

            const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE];

            apply_window(&s->dsp, s->windowed_samples, input_samples, s->mdct.window, AC3_WINDOW_SIZE);

            block->coeff_shift[ch] = normalize_samples(s);

            mdct512(&s->mdct, block->mdct_coef[ch], s->windowed_samples);

        }

    }

}


static int hls_slice_header(HEVCContext *s)

{

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

    SliceHeader *sh   = &s->sh;

    int i, ret;

    // Coded parameters

    sh->first_slice_in_pic_flag = get_bits1(gb);

    if ((IS_IDR(s) || IS_BLA(s)) && sh->first_slice_in_pic_flag) {

        s->seq_decode = (s->seq_decode + 1) & 0xff;

        s->max_ra     = INT_MAX;

        if (IS_IDR(s))

            ff_hevc_clear_refs(s);

    }

    sh->no_output_of_prior_pics_flag = 0;

    if (IS_IRAP(s))

        sh->no_output_of_prior_pics_flag = get_bits1(gb);

    sh->pps_id = get_ue_golomb_long(gb);

    if (sh->pps_id >= HEVC_MAX_PPS_COUNT || !s->ps.pps_list[sh->pps_id]) {

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

        return AVERROR_INVALIDDATA;

    }

    if (!sh->first_slice_in_pic_flag &&

        s->ps.pps != (HEVCPPS*)s->ps.pps_list[sh->pps_id]->data) {

        av_log(s->avctx, AV_LOG_ERROR, "PPS changed between slices.\n");

        return AVERROR_INVALIDDATA;

    }

    s->ps.pps = (HEVCPPS*)s->ps.pps_list[sh->pps_id]->data;

    if (s->nal_unit_type == HEVC_NAL_CRA_NUT && s->last_eos == 1)

        sh->no_output_of_prior_pics_flag = 1;

    if (s->ps.sps != (HEVCSPS*)s->ps.sps_list[s->ps.pps->sps_id]->data) {

        const HEVCSPS *sps = (HEVCSPS*)s->ps.sps_list[s->ps.pps->sps_id]->data;

        const HEVCSPS *last_sps = s->ps.sps;

        enum AVPixelFormat pix_fmt;

        if (last_sps && IS_IRAP(s) && s->nal_unit_type != HEVC_NAL_CRA_NUT) {

            if (sps->width != last_sps->width || sps->height != last_sps->height ||

                sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering !=

                last_sps->temporal_layer[last_sps->max_sub_layers - 1].max_dec_pic_buffering)

                sh->no_output_of_prior_pics_flag = 0;

        }

        ff_hevc_clear_refs(s);

        pix_fmt = get_format(s, sps);

        if (pix_fmt < 0)

            return pix_fmt;

        ret = set_sps(s, sps, pix_fmt);

        if (ret < 0)

            return ret;

        s->seq_decode = (s->seq_decode + 1) & 0xff;

        s->max_ra     = INT_MAX;

    }

    sh->dependent_slice_segment_flag = 0;

    if (!sh->first_slice_in_pic_flag) {

        int slice_address_length;

        if (s->ps.pps->dependent_slice_segments_enabled_flag)

            sh->dependent_slice_segment_flag = get_bits1(gb);

        slice_address_length = av_ceil_log2(s->ps.sps->ctb_width *

                                            s->ps.sps->ctb_height);

        sh->slice_segment_addr = get_bitsz(gb, slice_address_length);

        if (sh->slice_segment_addr >= s->ps.sps->ctb_width * s->ps.sps->ctb_height) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "Invalid slice segment address: %u.\n",

                   sh->slice_segment_addr);

            return AVERROR_INVALIDDATA;

        }

        if (!sh->dependent_slice_segment_flag) {

            sh->slice_addr = sh->slice_segment_addr;

            s->slice_idx++;

        }

    } else {

        sh->slice_segment_addr = sh->slice_addr = 0;

        s->slice_idx           = 0;

        s->slice_initialized   = 0;

    }

    if (!sh->dependent_slice_segment_flag) {

        s->slice_initialized = 0;

        for (i = 0; i < s->ps.pps->num_extra_slice_header_bits; i++)

            skip_bits(gb, 1);  // slice_reserved_undetermined_flag[]

        sh->slice_type = get_ue_golomb_long(gb);

        if (!(sh->slice_type == HEVC_SLICE_I ||

              sh->slice_type == HEVC_SLICE_P ||

              sh->slice_type == HEVC_SLICE_B)) {

            av_log(s->avctx, AV_LOG_ERROR, "Unknown slice type: %d.\n",

                   sh->slice_type);

            return AVERROR_INVALIDDATA;

        }

        if (IS_IRAP(s) && sh->slice_type != HEVC_SLICE_I) {

            av_log(s->avctx, AV_LOG_ERROR, "Inter slices in an IRAP frame.\n");

            return AVERROR_INVALIDDATA;

        }

        // when flag is not present, picture is inferred to be output

        sh->pic_output_flag = 1;

        if (s->ps.pps->output_flag_present_flag)

            sh->pic_output_flag = get_bits1(gb);

        if (s->ps.sps->separate_colour_plane_flag)

            sh->colour_plane_id = get_bits(gb, 2);

        if (!IS_IDR(s)) {

            int poc, pos;

            sh->pic_order_cnt_lsb = get_bits(gb, s->ps.sps->log2_max_poc_lsb);

            poc = ff_hevc_compute_poc(s->ps.sps, s->pocTid0, sh->pic_order_cnt_lsb, s->nal_unit_type);

            if (!sh->first_slice_in_pic_flag && poc != s->poc) {

                av_log(s->avctx, AV_LOG_WARNING,

                       "Ignoring POC change between slices: %d -> %d\n", s->poc, poc);

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

                    return AVERROR_INVALIDDATA;

                poc = s->poc;

            }

            s->poc = poc;

            sh->short_term_ref_pic_set_sps_flag = get_bits1(gb);

            pos = get_bits_left(gb);

            if (!sh->short_term_ref_pic_set_sps_flag) {

                ret = ff_hevc_decode_short_term_rps(gb, s->avctx, &sh->slice_rps, s->ps.sps, 1);

                if (ret < 0)

                    return ret;

                sh->short_term_rps = &sh->slice_rps;

            } else {

                int numbits, rps_idx;

                if (!s->ps.sps->nb_st_rps) {

                    av_log(s->avctx, AV_LOG_ERROR, "No ref lists in the SPS.\n");

                    return AVERROR_INVALIDDATA;

                }

                numbits = av_ceil_log2(s->ps.sps->nb_st_rps);

                rps_idx = numbits > 0 ? get_bits(gb, numbits) : 0;

                sh->short_term_rps = &s->ps.sps->st_rps[rps_idx];

            }

            sh->short_term_ref_pic_set_size = pos - get_bits_left(gb);

            pos = get_bits_left(gb);

            ret = decode_lt_rps(s, &sh->long_term_rps, gb);

            if (ret < 0) {

                av_log(s->avctx, AV_LOG_WARNING, "Invalid long term RPS.\n");

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

                    return AVERROR_INVALIDDATA;

            }

            sh->long_term_ref_pic_set_size = pos - get_bits_left(gb);

            if (s->ps.sps->sps_temporal_mvp_enabled_flag)

                sh->slice_temporal_mvp_enabled_flag = get_bits1(gb);

            else

                sh->slice_temporal_mvp_enabled_flag = 0;

        } else {

            s->sh.short_term_rps = NULL;

            s->poc               = 0;

        }

        /* 8.3.1 */

        if (sh->first_slice_in_pic_flag && s->temporal_id == 0 &&

            s->nal_unit_type != HEVC_NAL_TRAIL_N &&

            s->nal_unit_type != HEVC_NAL_TSA_N   &&

            s->nal_unit_type != HEVC_NAL_STSA_N  &&

            s->nal_unit_type != HEVC_NAL_RADL_N  &&

            s->nal_unit_type != HEVC_NAL_RADL_R  &&

            s->nal_unit_type != HEVC_NAL_RASL_N  &&

            s->nal_unit_type != HEVC_NAL_RASL_R)

            s->pocTid0 = s->poc;

        if (s->ps.sps->sao_enabled) {

            sh->slice_sample_adaptive_offset_flag[0] = get_bits1(gb);

            if (s->ps.sps->chroma_format_idc) {

                sh->slice_sample_adaptive_offset_flag[1] =

                sh->slice_sample_adaptive_offset_flag[2] = get_bits1(gb);

            }

        } else {

            sh->slice_sample_adaptive_offset_flag[0] = 0;

            sh->slice_sample_adaptive_offset_flag[1] = 0;

            sh->slice_sample_adaptive_offset_flag[2] = 0;

        }

        sh->nb_refs[L0] = sh->nb_refs[L1] = 0;

        if (sh->slice_type == HEVC_SLICE_P || sh->slice_type == HEVC_SLICE_B) {

            int nb_refs;

            sh->nb_refs[L0] = s->ps.pps->num_ref_idx_l0_default_active;

            if (sh->slice_type == HEVC_SLICE_B)

                sh->nb_refs[L1] = s->ps.pps->num_ref_idx_l1_default_active;

            if (get_bits1(gb)) { // num_ref_idx_active_override_flag

                sh->nb_refs[L0] = get_ue_golomb_long(gb) + 1;

                if (sh->slice_type == HEVC_SLICE_B)

                    sh->nb_refs[L1] = get_ue_golomb_long(gb) + 1;

            }

            if (sh->nb_refs[L0] > HEVC_MAX_REFS || sh->nb_refs[L1] > HEVC_MAX_REFS) {

                av_log(s->avctx, AV_LOG_ERROR, "Too many refs: %d/%d.\n",

                       sh->nb_refs[L0], sh->nb_refs[L1]);

                return AVERROR_INVALIDDATA;

            }

            sh->rpl_modification_flag[0] = 0;

            sh->rpl_modification_flag[1] = 0;

            nb_refs = ff_hevc_frame_nb_refs(s);

            if (!nb_refs) {

                av_log(s->avctx, AV_LOG_ERROR, "Zero refs for a frame with P or B slices.\n");

                return AVERROR_INVALIDDATA;

            }

            if (s->ps.pps->lists_modification_present_flag && nb_refs > 1) {

                sh->rpl_modification_flag[0] = get_bits1(gb);

                if (sh->rpl_modification_flag[0]) {

                    for (i = 0; i < sh->nb_refs[L0]; i++)

                        sh->list_entry_lx[0][i] = get_bits(gb, av_ceil_log2(nb_refs));

                }

                if (sh->slice_type == HEVC_SLICE_B) {

                    sh->rpl_modification_flag[1] = get_bits1(gb);

                    if (sh->rpl_modification_flag[1] == 1)

                        for (i = 0; i < sh->nb_refs[L1]; i++)

                            sh->list_entry_lx[1][i] = get_bits(gb, av_ceil_log2(nb_refs));

                }

            }

            if (sh->slice_type == HEVC_SLICE_B)

                sh->mvd_l1_zero_flag = get_bits1(gb);

            if (s->ps.pps->cabac_init_present_flag)

                sh->cabac_init_flag = get_bits1(gb);

            else

                sh->cabac_init_flag = 0;

            sh->collocated_ref_idx = 0;

            if (sh->slice_temporal_mvp_enabled_flag) {

                sh->collocated_list = L0;

                if (sh->slice_type == HEVC_SLICE_B)

                    sh->collocated_list = !get_bits1(gb);

                if (sh->nb_refs[sh->collocated_list] > 1) {

                    sh->collocated_ref_idx = get_ue_golomb_long(gb);

                    if (sh->collocated_ref_idx >= sh->nb_refs[sh->collocated_list]) {

                        av_log(s->avctx, AV_LOG_ERROR,

                               "Invalid collocated_ref_idx: %d.\n",

                               sh->collocated_ref_idx);

                        return AVERROR_INVALIDDATA;

                    }

                }

            }

            if ((s->ps.pps->weighted_pred_flag   && sh->slice_type == HEVC_SLICE_P) ||

                (s->ps.pps->weighted_bipred_flag && sh->slice_type == HEVC_SLICE_B)) {

                pred_weight_table(s, gb);

            }

            sh->max_num_merge_cand = 5 - get_ue_golomb_long(gb);

            if (sh->max_num_merge_cand < 1 || sh->max_num_merge_cand > 5) {

                av_log(s->avctx, AV_LOG_ERROR,

                       "Invalid number of merging MVP candidates: %d.\n",

                       sh->max_num_merge_cand);

                return AVERROR_INVALIDDATA;

            }

        }

        sh->slice_qp_delta = get_se_golomb(gb);

        if (s->ps.pps->pic_slice_level_chroma_qp_offsets_present_flag) {

            sh->slice_cb_qp_offset = get_se_golomb(gb);

            sh->slice_cr_qp_offset = get_se_golomb(gb);

        } else {

            sh->slice_cb_qp_offset = 0;

            sh->slice_cr_qp_offset = 0;

        }

        if (s->ps.pps->chroma_qp_offset_list_enabled_flag)

            sh->cu_chroma_qp_offset_enabled_flag = get_bits1(gb);

        else

            sh->cu_chroma_qp_offset_enabled_flag = 0;

        if (s->ps.pps->deblocking_filter_control_present_flag) {

            int deblocking_filter_override_flag = 0;

            if (s->ps.pps->deblocking_filter_override_enabled_flag)

                deblocking_filter_override_flag = get_bits1(gb);

            if (deblocking_filter_override_flag) {

                sh->disable_deblocking_filter_flag = get_bits1(gb);

                if (!sh->disable_deblocking_filter_flag) {

                    int beta_offset_div2 = get_se_golomb(gb);

                    int tc_offset_div2   = get_se_golomb(gb) ;

                    if (beta_offset_div2 < -6 || beta_offset_div2 > 6 ||

                        tc_offset_div2   < -6 || tc_offset_div2   > 6) {

                        av_log(s->avctx, AV_LOG_ERROR,

                            "Invalid deblock filter offsets: %d, %d\n",

                            beta_offset_div2, tc_offset_div2);

                        return AVERROR_INVALIDDATA;

                    }

                    sh->beta_offset = beta_offset_div2 * 2;

                    sh->tc_offset   =   tc_offset_div2 * 2;

                }

            } else {

                sh->disable_deblocking_filter_flag = s->ps.pps->disable_dbf;

                sh->beta_offset                    = s->ps.pps->beta_offset;

                sh->tc_offset                      = s->ps.pps->tc_offset;

            }

        } else {

            sh->disable_deblocking_filter_flag = 0;

            sh->beta_offset                    = 0;

            sh->tc_offset                      = 0;

        }

        if (s->ps.pps->seq_loop_filter_across_slices_enabled_flag &&

            (sh->slice_sample_adaptive_offset_flag[0] ||

             sh->slice_sample_adaptive_offset_flag[1] ||

             !sh->disable_deblocking_filter_flag)) {

            sh->slice_loop_filter_across_slices_enabled_flag = get_bits1(gb);

        } else {

            sh->slice_loop_filter_across_slices_enabled_flag = s->ps.pps->seq_loop_filter_across_slices_enabled_flag;

        }

    } else if (!s->slice_initialized) {

        av_log(s->avctx, AV_LOG_ERROR, "Independent slice segment missing.\n");

        return AVERROR_INVALIDDATA;

    }

    sh->num_entry_point_offsets = 0;

    if (s->ps.pps->tiles_enabled_flag || s->ps.pps->entropy_coding_sync_enabled_flag) {

        unsigned num_entry_point_offsets = get_ue_golomb_long(gb);

        // It would be possible to bound this tighter but this here is simpler

        if (num_entry_point_offsets > get_bits_left(gb)) {

            av_log(s->avctx, AV_LOG_ERROR, "num_entry_point_offsets %d is invalid\n", num_entry_point_offsets);

            return AVERROR_INVALIDDATA;

        }

        sh->num_entry_point_offsets = num_entry_point_offsets;

        if (sh->num_entry_point_offsets > 0) {

            int offset_len = get_ue_golomb_long(gb) + 1;

            if (offset_len < 1 || offset_len > 32) {

                sh->num_entry_point_offsets = 0;

                av_log(s->avctx, AV_LOG_ERROR, "offset_len %d is invalid\n", offset_len);

                return AVERROR_INVALIDDATA;

            }

            av_freep(&sh->entry_point_offset);

            av_freep(&sh->offset);

            av_freep(&sh->size);

            sh->entry_point_offset = av_malloc_array(sh->num_entry_point_offsets, sizeof(unsigned));

            sh->offset = av_malloc_array(sh->num_entry_point_offsets, sizeof(int));

            sh->size = av_malloc_array(sh->num_entry_point_offsets, sizeof(int));

            if (!sh->entry_point_offset || !sh->offset || !sh->size) {

                sh->num_entry_point_offsets = 0;

                av_log(s->avctx, AV_LOG_ERROR, "Failed to allocate memory\n");

                return AVERROR(ENOMEM);

            }

            for (i = 0; i < sh->num_entry_point_offsets; i++) {

                unsigned val = get_bits_long(gb, offset_len);

                sh->entry_point_offset[i] = val + 1; // +1; // +1 to get the size

            }

            if (s->threads_number > 1 && (s->ps.pps->num_tile_rows > 1 || s->ps.pps->num_tile_columns > 1)) {

                s->enable_parallel_tiles = 0; // TODO: you can enable tiles in parallel here

                s->threads_number = 1;

            } else

                s->enable_parallel_tiles = 0;

        } else

            s->enable_parallel_tiles = 0;

    }

    if (s->ps.pps->slice_header_extension_present_flag) {

        unsigned int length = get_ue_golomb_long(gb);

        if (length*8LL > get_bits_left(gb)) {

            av_log(s->avctx, AV_LOG_ERROR, "too many slice_header_extension_data_bytes\n");

            return AVERROR_INVALIDDATA;

        }

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

            skip_bits(gb, 8);  // slice_header_extension_data_byte

    }

    // Inferred parameters

    sh->slice_qp = 26U + s->ps.pps->pic_init_qp_minus26 + sh->slice_qp_delta;

    if (sh->slice_qp > 51 ||

        sh->slice_qp < -s->ps.sps->qp_bd_offset) {

        av_log(s->avctx, AV_LOG_ERROR,

               "The slice_qp %d is outside the valid range "

               "[%d, 51].\n",

               sh->slice_qp,

               -s->ps.sps->qp_bd_offset);

        return AVERROR_INVALIDDATA;

    }

    sh->slice_ctb_addr_rs = sh->slice_segment_addr;

    if (!s->sh.slice_ctb_addr_rs && s->sh.dependent_slice_segment_flag) {

        av_log(s->avctx, AV_LOG_ERROR, "Impossible slice segment.\n");

        return AVERROR_INVALIDDATA;

    }

    if (get_bits_left(gb) < 0) {

        av_log(s->avctx, AV_LOG_ERROR,

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

        return AVERROR_INVALIDDATA;

    }

    s->HEVClc->first_qp_group = !s->sh.dependent_slice_segment_flag;

    if (!s->ps.pps->cu_qp_delta_enabled_flag)

        s->HEVClc->qp_y = s->sh.slice_qp;

    s->slice_initialized = 1;

    s->HEVClc->tu.cu_qp_offset_cb = 0;

    s->HEVClc->tu.cu_qp_offset_cr = 0;

    return 0;

}


static void pciej_write(void *opaque, uint32_t addr, uint32_t val)

{

    BusState *bus = opaque;

    DeviceState *qdev, *next;

    PCIDevice *dev;

    int slot = ffs(val) - 1;

    QLIST_FOREACH_SAFE(qdev, &bus->children, sibling, next) {

        dev = DO_UPCAST(PCIDevice, qdev, qdev);

        if (PCI_SLOT(dev->devfn) == slot) {

            qdev_free(qdev);

        }

    }

    PIIX4_DPRINTF("pciej write %x <== %d\n", addr, val);

}


void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp)

{

    DeviceState *qdev = DEVICE(vdev);

    BusState *qbus = BUS(qdev_get_parent_bus(qdev));

    VirtioBusState *bus = VIRTIO_BUS(qbus);

    VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);

    VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);

    bool has_iommu = virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);

    DPRINTF("%s: plug device.\n", qbus->name);

    if (klass->pre_plugged != NULL) {

        klass->pre_plugged(qbus->parent, errp);

    }

    /* Get the features of the plugged device. */

    assert(vdc->get_features != NULL);

    vdev->host_features = vdc->get_features(vdev, vdev->host_features,

                                            errp);

    if (klass->device_plugged != NULL) {

        klass->device_plugged(qbus->parent, errp);

    }

    if (klass->get_dma_as != NULL && has_iommu) {

        virtio_add_feature(&vdev->host_features, VIRTIO_F_IOMMU_PLATFORM);

        vdev->dma_as = klass->get_dma_as(qbus->parent);

    } else {

        vdev->dma_as = &address_space_memory;

    }

}


static size_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)

{

    size_t old_offset = offset;

    va_list ap;

    int i;

    va_start(ap, fmt);

    for (i = 0; fmt[i]; i++) {

        switch (fmt[i]) {

        case 'b': {

            uint8_t *valp = va_arg(ap, uint8_t *);

            offset += pdu_unpack(valp, pdu, offset, sizeof(*valp));

            break;

        }

        case 'w': {

            uint16_t val, *valp;

            valp = va_arg(ap, uint16_t *);

            offset += pdu_unpack(&val, pdu, offset, sizeof(val));

            *valp = le16_to_cpu(val);

            break;

        }

        case 'd': {

            uint32_t val, *valp;

            valp = va_arg(ap, uint32_t *);

            offset += pdu_unpack(&val, pdu, offset, sizeof(val));

            *valp = le32_to_cpu(val);

            break;

        }

        case 'q': {

            uint64_t val, *valp;

            valp = va_arg(ap, uint64_t *);

            offset += pdu_unpack(&val, pdu, offset, sizeof(val));

            *valp = le64_to_cpu(val);

            break;

        }

        case 'v': {

            struct iovec *iov = va_arg(ap, struct iovec *);

            int *iovcnt = va_arg(ap, int *);

            *iovcnt = pdu_copy_sg(pdu, offset, 0, iov);

            break;

        }

        case 's': {

            V9fsString *str = va_arg(ap, V9fsString *);

            offset += pdu_unmarshal(pdu, offset, "w", &str->size);

            /* FIXME: sanity check str->size */

            str->data = g_malloc(str->size + 1);

            offset += pdu_unpack(str->data, pdu, offset, str->size);

            str->data[str->size] = 0;

            break;

        }

        case 'Q': {

            V9fsQID *qidp = va_arg(ap, V9fsQID *);

            offset += pdu_unmarshal(pdu, offset, "bdq",

                        &qidp->type, &qidp->version, &qidp->path);

            break;

        }

        case 'S': {

            V9fsStat *statp = va_arg(ap, V9fsStat *);

            offset += pdu_unmarshal(pdu, offset, "wwdQdddqsssssddd",

                        &statp->size, &statp->type, &statp->dev,

                        &statp->qid, &statp->mode, &statp->atime,

                        &statp->mtime, &statp->length,

                        &statp->name, &statp->uid, &statp->gid,

                        &statp->muid, &statp->extension,

                        &statp->n_uid, &statp->n_gid,

                        &statp->n_muid);

            break;

        }

        case 'I': {

            V9fsIattr *iattr = va_arg(ap, V9fsIattr *);

            offset += pdu_unmarshal(pdu, offset, "ddddqqqqq",

                        &iattr->valid, &iattr->mode,

                        &iattr->uid, &iattr->gid, &iattr->size,

                        &iattr->atime_sec, &iattr->atime_nsec,

                        &iattr->mtime_sec, &iattr->mtime_nsec);

            break;

        }

        default:

            break;

        }

    }

    va_end(ap);

    return offset - old_offset;

}


void unix_start_incoming_migration(const char *path, Error **errp)

{

    int s;

    s = unix_listen(path, NULL, 0, errp);

    if (s < 0) {

        return;

    }

    qemu_set_fd_handler2(s, NULL, unix_accept_incoming_migration, NULL,

                         (void *)(intptr_t)s);

}


static inline int draw_glyph_rgb(AVFilterBufferRef *picref, FT_Bitmap *bitmap,

                                 unsigned int x, unsigned int y,

                                 unsigned int width, unsigned int height, int pixel_step,

                                 const uint8_t rgba_color[4], const uint8_t rgba_map[4])

{

    int r, c, alpha;

    uint8_t *p;

    uint8_t src_val;

    for (r = 0; r < bitmap->rows && r+y < height; r++) {

        for (c = 0; c < bitmap->width && c+x < width; c++) {

            /* get intensity value in the glyph bitmap (source) */

            src_val = GET_BITMAP_VAL(r, c);

            if (!src_val)

                continue;

            SET_PIXEL_RGB(picref, rgba_color, src_val, c+x, y+r, pixel_step,

                          rgba_map[0], rgba_map[1], rgba_map[2], rgba_map[3]);

        }

    }

    return 0;

}


static void apply_unsharp(      uint8_t *dst, int dst_stride,

                          const uint8_t *src, int src_stride,

                          int width, int height, FilterParam *fp)

{

    uint32_t **sc = fp->sc;

    uint32_t sr[(MAX_SIZE * MAX_SIZE) - 1], tmp1, tmp2;

    int32_t res;

    int x, y, z;

    const uint8_t *src2;

    if (!fp->amount) {

        if (dst_stride == src_stride)

            memcpy(dst, src, src_stride * height);

        else

            for (y = 0; y < height; y++, dst += dst_stride, src += src_stride)

                memcpy(dst, src, width);

        return;

    }

    for (y = 0; y < 2 * fp->steps_y; y++)

        memset(sc[y], 0, sizeof(sc[y][0]) * (width + 2 * fp->steps_x));

    for (y = -fp->steps_y; y < height + fp->steps_y; y++) {

        if (y < height)

            src2 = src;

        memset(sr, 0, sizeof(sr[0]) * (2 * fp->steps_x - 1));

        for (x = -fp->steps_x; x < width + fp->steps_x; x++) {

            tmp1 = x <= 0 ? src2[0] : x >= width ? src2[width-1] : src2[x];

            for (z = 0; z < fp->steps_x * 2; z += 2) {

                tmp2 = sr[z + 0] + tmp1; sr[z + 0] = tmp1;

                tmp1 = sr[z + 1] + tmp2; sr[z + 1] = tmp2;

            }

            for (z = 0; z < fp->steps_y * 2; z += 2) {

                tmp2 = sc[z + 0][x + fp->steps_x] + tmp1; sc[z + 0][x + fp->steps_x] = tmp1;

                tmp1 = sc[z + 1][x + fp->steps_x] + tmp2; sc[z + 1][x + fp->steps_x] = tmp2;

            }

            if (x >= fp->steps_x && y >= fp->steps_y) {

                const uint8_t *srx = src - fp->steps_y * src_stride + x - fp->steps_x;

                uint8_t       *dsx = dst - fp->steps_y * dst_stride + x - fp->steps_x;

                res = (int32_t)*srx + ((((int32_t) * srx - (int32_t)((tmp1 + fp->halfscale) >> fp->scalebits)) * fp->amount) >> 16);

                *dsx = av_clip_uint8(res);

            }

        }

        if (y >= 0) {

            dst += dst_stride;

            src += src_stride;

        }

    }

}


static void acquire_privilege(const char *name, Error **errp)

{

    HANDLE token;

    TOKEN_PRIVILEGES priv;

    Error *local_err = NULL;

    if (OpenProcessToken(GetCurrentProcess(),

        TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &token))

    {

        if (!LookupPrivilegeValue(NULL, name, &priv.Privileges[0].Luid)) {

            error_set(&local_err, QERR_QGA_COMMAND_FAILED,

                      "no luid for requested privilege");

            goto out;

        }

        priv.PrivilegeCount = 1;

        priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

        if (!AdjustTokenPrivileges(token, FALSE, &priv, 0, NULL, 0)) {

            error_set(&local_err, QERR_QGA_COMMAND_FAILED,

                      "unable to acquire requested privilege");

            goto out;

        }

        CloseHandle(token);

    } else {

        error_set(&local_err, QERR_QGA_COMMAND_FAILED,

                  "failed to open privilege token");

    }

out:

    if (local_err) {

        error_propagate(errp, local_err);

    }

}