static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_t size_, int do_interrupt)

{

    RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque;

    /* size is the length of the buffer passed to the driver */

    int size = size_;

    const uint8_t *dot1q_buf = NULL;

    uint32_t packet_header = 0;

    uint8_t buf1[MIN_BUF_SIZE + VLAN_HLEN];

    static const uint8_t broadcast_macaddr[6] =

        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

    DEBUG_PRINT((">>> RTL8139: received len=%d\n", size));

    /* test if board clock is stopped */

    if (!s->clock_enabled)

    {

        DEBUG_PRINT(("RTL8139: stopped ==========================\n"));

        return -1;

    }

    /* first check if receiver is enabled */

    if (!rtl8139_receiver_enabled(s))

    {

        DEBUG_PRINT(("RTL8139: receiver disabled ================\n"));

        return -1;

    }

    /* XXX: check this */

    if (s->RxConfig & AcceptAllPhys) {

        /* promiscuous: receive all */

        DEBUG_PRINT((">>> RTL8139: packet received in promiscuous mode\n"));

    } else {

        if (!memcmp(buf,  broadcast_macaddr, 6)) {

            /* broadcast address */

            if (!(s->RxConfig & AcceptBroadcast))

            {

                DEBUG_PRINT((">>> RTL8139: broadcast packet rejected\n"));

                /* update tally counter */

                ++s->tally_counters.RxERR;

                return size;

            }

            packet_header |= RxBroadcast;

            DEBUG_PRINT((">>> RTL8139: broadcast packet received\n"));

            /* update tally counter */

            ++s->tally_counters.RxOkBrd;

        } else if (buf[0] & 0x01) {

            /* multicast */

            if (!(s->RxConfig & AcceptMulticast))

            {

                DEBUG_PRINT((">>> RTL8139: multicast packet rejected\n"));

                /* update tally counter */

                ++s->tally_counters.RxERR;

                return size;

            }

            int mcast_idx = compute_mcast_idx(buf);

            if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))

            {

                DEBUG_PRINT((">>> RTL8139: multicast address mismatch\n"));

                /* update tally counter */

                ++s->tally_counters.RxERR;

                return size;

            }

            packet_header |= RxMulticast;

            DEBUG_PRINT((">>> RTL8139: multicast packet received\n"));

            /* update tally counter */

            ++s->tally_counters.RxOkMul;

        } else if (s->phys[0] == buf[0] &&

                   s->phys[1] == buf[1] &&

                   s->phys[2] == buf[2] &&

                   s->phys[3] == buf[3] &&

                   s->phys[4] == buf[4] &&

                   s->phys[5] == buf[5]) {

            /* match */

            if (!(s->RxConfig & AcceptMyPhys))

            {

                DEBUG_PRINT((">>> RTL8139: rejecting physical address matching packet\n"));

                /* update tally counter */

                ++s->tally_counters.RxERR;

                return size;

            }

            packet_header |= RxPhysical;

            DEBUG_PRINT((">>> RTL8139: physical address matching packet received\n"));

            /* update tally counter */

            ++s->tally_counters.RxOkPhy;

        } else {

            DEBUG_PRINT((">>> RTL8139: unknown packet\n"));

            /* update tally counter */

            ++s->tally_counters.RxERR;

            return size;

        }

    }

    /* if too small buffer, then expand it

     * Include some tailroom in case a vlan tag is later removed. */

    if (size < MIN_BUF_SIZE + VLAN_HLEN) {

        memcpy(buf1, buf, size);

        memset(buf1 + size, 0, MIN_BUF_SIZE + VLAN_HLEN - size);

        buf = buf1;

        if (size < MIN_BUF_SIZE) {

            size = MIN_BUF_SIZE;

        }

    }

    if (rtl8139_cp_receiver_enabled(s))

    {

        DEBUG_PRINT(("RTL8139: in C+ Rx mode ================\n"));

        /* begin C+ receiver mode */

/* w0 ownership flag */

#define CP_RX_OWN (1<<31)

/* w0 end of ring flag */

#define CP_RX_EOR (1<<30)

/* w0 bits 0...12 : buffer size */

#define CP_RX_BUFFER_SIZE_MASK ((1<<13) - 1)

/* w1 tag available flag */

#define CP_RX_TAVA (1<<16)

/* w1 bits 0...15 : VLAN tag */

#define CP_RX_VLAN_TAG_MASK ((1<<16) - 1)

/* w2 low  32bit of Rx buffer ptr */

/* w3 high 32bit of Rx buffer ptr */

        int descriptor = s->currCPlusRxDesc;

        target_phys_addr_t cplus_rx_ring_desc;

        cplus_rx_ring_desc = rtl8139_addr64(s->RxRingAddrLO, s->RxRingAddrHI);

        cplus_rx_ring_desc += 16 * descriptor;

        DEBUG_PRINT(("RTL8139: +++ C+ mode reading RX descriptor %d from host memory at %08x %08x = %016" PRIx64 "\n",

               descriptor, s->RxRingAddrHI, s->RxRingAddrLO, (uint64_t)cplus_rx_ring_desc));

        uint32_t val, rxdw0,rxdw1,rxbufLO,rxbufHI;

        cpu_physical_memory_read(cplus_rx_ring_desc,    (uint8_t *)&val, 4);

        rxdw0 = le32_to_cpu(val);

        cpu_physical_memory_read(cplus_rx_ring_desc+4,  (uint8_t *)&val, 4);

        rxdw1 = le32_to_cpu(val);

        cpu_physical_memory_read(cplus_rx_ring_desc+8,  (uint8_t *)&val, 4);

        rxbufLO = le32_to_cpu(val);

        cpu_physical_memory_read(cplus_rx_ring_desc+12, (uint8_t *)&val, 4);

        rxbufHI = le32_to_cpu(val);

        DEBUG_PRINT(("RTL8139: +++ C+ mode RX descriptor %d %08x %08x %08x %08x\n",

               descriptor,

               rxdw0, rxdw1, rxbufLO, rxbufHI));

        if (!(rxdw0 & CP_RX_OWN))

        {

            DEBUG_PRINT(("RTL8139: C+ Rx mode : descriptor %d is owned by host\n", descriptor));

            s->IntrStatus |= RxOverflow;

            ++s->RxMissed;

            /* update tally counter */

            ++s->tally_counters.RxERR;

            ++s->tally_counters.MissPkt;

            rtl8139_update_irq(s);

            return size_;

        }

        uint32_t rx_space = rxdw0 & CP_RX_BUFFER_SIZE_MASK;

        /* write VLAN info to descriptor variables. */

        if (s->CpCmd & CPlusRxVLAN && be16_to_cpup((uint16_t *)

                &buf[ETHER_ADDR_LEN * 2]) == ETH_P_8021Q) {

            dot1q_buf = &buf[ETHER_ADDR_LEN * 2];

            size -= VLAN_HLEN;

            /* if too small buffer, use the tailroom added duing expansion */

            if (size < MIN_BUF_SIZE) {

                size = MIN_BUF_SIZE;

            }

            rxdw1 &= ~CP_RX_VLAN_TAG_MASK;

            /* BE + ~le_to_cpu()~ + cpu_to_le() = BE */

            rxdw1 |= CP_RX_TAVA | le16_to_cpup((uint16_t *)

                &dot1q_buf[ETHER_TYPE_LEN]);

            DEBUG_PRINT(("RTL8139: C+ Rx mode : extracted vlan tag with tci: "

                    "%u\n", be16_to_cpup((uint16_t *)

                        &dot1q_buf[ETHER_TYPE_LEN])));

        } else {

            /* reset VLAN tag flag */

            rxdw1 &= ~CP_RX_TAVA;

        }

        /* TODO: scatter the packet over available receive ring descriptors space */

        if (size+4 > rx_space)

        {

            DEBUG_PRINT(("RTL8139: C+ Rx mode : descriptor %d size %d received %d + 4\n",

                   descriptor, rx_space, size));

            s->IntrStatus |= RxOverflow;

            ++s->RxMissed;

            /* update tally counter */

            ++s->tally_counters.RxERR;

            ++s->tally_counters.MissPkt;

            rtl8139_update_irq(s);

            return size_;

        }

        target_phys_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI);

        /* receive/copy to target memory */

        if (dot1q_buf) {

            cpu_physical_memory_write(rx_addr, buf, 2 * ETHER_ADDR_LEN);

            cpu_physical_memory_write(rx_addr + 2 * ETHER_ADDR_LEN,

                buf + 2 * ETHER_ADDR_LEN + VLAN_HLEN,

                size - 2 * ETHER_ADDR_LEN);

        } else {

            cpu_physical_memory_write(rx_addr, buf, size);

        }

        if (s->CpCmd & CPlusRxChkSum)

        {

            /* do some packet checksumming */

        }

        /* write checksum */

        val = cpu_to_le32(crc32(0, buf, size_));

        cpu_physical_memory_write( rx_addr+size, (uint8_t *)&val, 4);

/* first segment of received packet flag */

#define CP_RX_STATUS_FS (1<<29)

/* last segment of received packet flag */

#define CP_RX_STATUS_LS (1<<28)

/* multicast packet flag */

#define CP_RX_STATUS_MAR (1<<26)

/* physical-matching packet flag */

#define CP_RX_STATUS_PAM (1<<25)

/* broadcast packet flag */

#define CP_RX_STATUS_BAR (1<<24)

/* runt packet flag */

#define CP_RX_STATUS_RUNT (1<<19)

/* crc error flag */

#define CP_RX_STATUS_CRC (1<<18)

/* IP checksum error flag */

#define CP_RX_STATUS_IPF (1<<15)

/* UDP checksum error flag */

#define CP_RX_STATUS_UDPF (1<<14)

/* TCP checksum error flag */

#define CP_RX_STATUS_TCPF (1<<13)

        /* transfer ownership to target */

        rxdw0 &= ~CP_RX_OWN;

        /* set first segment bit */

        rxdw0 |= CP_RX_STATUS_FS;

        /* set last segment bit */

        rxdw0 |= CP_RX_STATUS_LS;

        /* set received packet type flags */

        if (packet_header & RxBroadcast)

            rxdw0 |= CP_RX_STATUS_BAR;

        if (packet_header & RxMulticast)

            rxdw0 |= CP_RX_STATUS_MAR;

        if (packet_header & RxPhysical)

            rxdw0 |= CP_RX_STATUS_PAM;

        /* set received size */

        rxdw0 &= ~CP_RX_BUFFER_SIZE_MASK;

        rxdw0 |= (size+4);

        /* update ring data */

        val = cpu_to_le32(rxdw0);

        cpu_physical_memory_write(cplus_rx_ring_desc,    (uint8_t *)&val, 4);

        val = cpu_to_le32(rxdw1);

        cpu_physical_memory_write(cplus_rx_ring_desc+4,  (uint8_t *)&val, 4);

        /* update tally counter */

        ++s->tally_counters.RxOk;

        /* seek to next Rx descriptor */

        if (rxdw0 & CP_RX_EOR)

        {

            s->currCPlusRxDesc = 0;

        }

        else

        {

            ++s->currCPlusRxDesc;

        }

        DEBUG_PRINT(("RTL8139: done C+ Rx mode ----------------\n"));

    }

    else

    {

        DEBUG_PRINT(("RTL8139: in ring Rx mode ================\n"));

        /* begin ring receiver mode */

        int avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr, s->RxBufferSize);

        /* if receiver buffer is empty then avail == 0 */

        if (avail != 0 && size + 8 >= avail)

        {

            DEBUG_PRINT(("rx overflow: rx buffer length %d head 0x%04x read 0x%04x === available 0x%04x need 0x%04x\n",

                   s->RxBufferSize, s->RxBufAddr, s->RxBufPtr, avail, size + 8));

            s->IntrStatus |= RxOverflow;

            ++s->RxMissed;

            rtl8139_update_irq(s);

            return size_;

        }

        packet_header |= RxStatusOK;

        packet_header |= (((size+4) << 16) & 0xffff0000);

        /* write header */

        uint32_t val = cpu_to_le32(packet_header);

        rtl8139_write_buffer(s, (uint8_t *)&val, 4);

        rtl8139_write_buffer(s, buf, size);

        /* write checksum */

        val = cpu_to_le32(crc32(0, buf, size));

        rtl8139_write_buffer(s, (uint8_t *)&val, 4);

        /* correct buffer write pointer */

        s->RxBufAddr = MOD2((s->RxBufAddr + 3) & ~0x3, s->RxBufferSize);

        /* now we can signal we have received something */

        DEBUG_PRINT(("   received: rx buffer length %d head 0x%04x read 0x%04x\n",

               s->RxBufferSize, s->RxBufAddr, s->RxBufPtr));

    }

    s->IntrStatus |= RxOK;

    if (do_interrupt)

    {

        rtl8139_update_irq(s);

    }

    return size_;

}


static void decode_mb(MadContext *t, int inter)

{

    MpegEncContext *s = &t->s;

    int mv_map = 0;

    int mv_x, mv_y;

    int j;

    if (inter) {

        int v = decode210(&s->gb);

        if (v < 2) {

            mv_map = v ? get_bits(&s->gb, 6) : 63;

            mv_x = decode_motion(&s->gb);

            mv_y = decode_motion(&s->gb);

        } else {

            mv_map = 0;

        }

    }

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

        if (mv_map & (1<<j)) {  // mv_x and mv_y are guarded by mv_map

            int add = 2*decode_motion(&s->gb);

            comp_block(t, s->mb_x, s->mb_y, j, mv_x, mv_y, add);

        } else {

            s->dsp.clear_block(t->block);

            decode_block_intra(t, t->block);

            idct_put(t, t->block, s->mb_x, s->mb_y, j);

        }

    }

}


static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output)

{

    DVBSubContext *ctx = avctx->priv_data;

    DVBSubRegionDisplay *display;

    DVBSubDisplayDefinition *display_def = ctx->display_definition;

    DVBSubRegion *region;

    AVSubtitleRect *rect;

    DVBSubCLUT *clut;

    uint32_t *clut_table;

    int i;

    int offset_x=0, offset_y=0;

    int ret = 0;

    if (display_def) {

        offset_x = display_def->x;

        offset_y = display_def->y;

    }

    /* Not touching AVSubtitles again*/

    if(sub->num_rects) {

        avpriv_request_sample(ctx, "Different Version of Segment asked Twice");

        return AVERROR_PATCHWELCOME;

    }

    for (display = ctx->display_list; display; display = display->next) {

        region = get_region(ctx, display->region_id);

        if (region && region->dirty)

            sub->num_rects++;

    }

    if(ctx->compute_edt == 0) {

        sub->end_display_time = ctx->time_out * 1000;

        *got_output = 1;

    } else if (ctx->prev_start != AV_NOPTS_VALUE) {

        sub->end_display_time = av_rescale_q((sub->pts - ctx->prev_start ), AV_TIME_BASE_Q, (AVRational){ 1, 1000 }) - 1;

        *got_output = 1;

    }

    if (sub->num_rects > 0) {

        sub->rects = av_mallocz_array(sizeof(*sub->rects), sub->num_rects);

        if (!sub->rects) {

            ret = AVERROR(ENOMEM);

            goto fail;

        }

        for (i = 0; i < sub->num_rects; i++) {

            sub->rects[i] = av_mallocz(sizeof(*sub->rects[i]));

            if (!sub->rects[i]) {

                ret = AVERROR(ENOMEM);

                goto fail;

            }

        }

        i = 0;

        for (display = ctx->display_list; display; display = display->next) {

            region = get_region(ctx, display->region_id);

            if (!region)

                continue;

            if (!region->dirty)

                continue;

            rect = sub->rects[i];

            rect->x = display->x_pos + offset_x;

            rect->y = display->y_pos + offset_y;

            rect->w = region->width;

            rect->h = region->height;

            rect->nb_colors = (1 << region->depth);

            rect->type      = SUBTITLE_BITMAP;

            rect->linesize[0] = region->width;

            clut = get_clut(ctx, region->clut);

            if (!clut)

                clut = &default_clut;

            switch (region->depth) {

            case 2:

                clut_table = clut->clut4;

                break;

            case 8:

                clut_table = clut->clut256;

                break;

            case 4:

            default:

                clut_table = clut->clut16;

                break;

            }

            rect->data[1] = av_mallocz(AVPALETTE_SIZE);

            if (!rect->data[1]) {

                ret = AVERROR(ENOMEM);

                goto fail;

            }

            memcpy(rect->data[1], clut_table, (1 << region->depth) * sizeof(uint32_t));

            rect->data[0] = av_malloc(region->buf_size);

            if (!rect->data[0]) {

                ret = AVERROR(ENOMEM);

                goto fail;

            }

            memcpy(rect->data[0], region->pbuf, region->buf_size);

            if ((clut == &default_clut && ctx->compute_clut == -1) || ctx->compute_clut == 1)

                compute_default_clut(rect, rect->w, rect->h);

#if FF_API_AVPICTURE

FF_DISABLE_DEPRECATION_WARNINGS

{

            int j;

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

                rect->pict.data[j] = rect->data[j];

                rect->pict.linesize[j] = rect->linesize[j];

            }

}

FF_ENABLE_DEPRECATION_WARNINGS

#endif

            i++;

        }

    }

    return 0;

fail:

    if (sub->rects) {

        for(i=0; i<sub->num_rects; i++) {

            rect = sub->rects[i];

            if (rect) {

                av_freep(&rect->data[0]);

                av_freep(&rect->data[1]);

            }

            av_freep(&sub->rects[i]);

        }

        av_freep(&sub->rects);

    }

    sub->num_rects = 0;

    return ret;

}


static bool vexpress_cfgctrl_read(arm_sysctl_state *s, unsigned int dcc,

                                  unsigned int function, unsigned int site,

                                  unsigned int position, unsigned int device,

                                  uint32_t *val)

{

    /* We don't support anything other than DCC 0, board stack position 0

     * or sites other than motherboard/daughterboard:

     */

    if (dcc != 0 || position != 0 ||

        (site != SYS_CFG_SITE_MB && site != SYS_CFG_SITE_DB1)) {

        goto cfgctrl_unimp;

    }

    switch (function) {

    case SYS_CFG_VOLT:

        if (site == SYS_CFG_SITE_DB1 && device < s->db_num_vsensors) {

            *val = s->db_voltage[device];

            return true;

        }

        if (site == SYS_CFG_SITE_MB && device == 0) {

            /* There is only one motherboard voltage sensor:

             * VIO : 3.3V : bus voltage between mother and daughterboard

             */

            *val = 3300000;

            return true;

        }

        break;

    case SYS_CFG_OSC:

        if (site == SYS_CFG_SITE_MB && device < sizeof(s->mb_clock)) {

            /* motherboard clock */

            *val = s->mb_clock[device];

            return true;

        }

        if (site == SYS_CFG_SITE_DB1 && device < s->db_num_clocks) {

            /* daughterboard clock */

            *val = s->db_clock[device];

            return true;

        }

        break;

    default:

        break;

    }

cfgctrl_unimp:

    qemu_log_mask(LOG_UNIMP,

                  "arm_sysctl: Unimplemented SYS_CFGCTRL read of function "

                  "0x%x DCC 0x%x site 0x%x position 0x%x device 0x%x\n",

                  function, dcc, site, position, device);

    return false;

}


static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip, int *value, int codingset)

{

    GetBitContext *gb = &v->s.gb;

    int index, escape, run = 0, level = 0, lst = 0;

    index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);

    if (index != vc1_ac_sizes[codingset] - 1) {

        run = vc1_index_decode_table[codingset][index][0];

        level = vc1_index_decode_table[codingset][index][1];

        lst = index >= vc1_last_decode_table[codingset];

        if(get_bits1(gb))

            level = -level;

    } else {

        escape = decode210(gb);

        if (escape != 2) {

            index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);

            run = vc1_index_decode_table[codingset][index][0];

            level = vc1_index_decode_table[codingset][index][1];

            lst = index >= vc1_last_decode_table[codingset];

            if(escape == 0) {

                if(lst)

                    level += vc1_last_delta_level_table[codingset][run];

                else

                    level += vc1_delta_level_table[codingset][run];

            } else {

                if(lst)

                    run += vc1_last_delta_run_table[codingset][level] + 1;

                else

                    run += vc1_delta_run_table[codingset][level] + 1;

            }

            if(get_bits1(gb))

                level = -level;

        } else {

            int sign;

            lst = get_bits1(gb);

            if(v->s.esc3_level_length == 0) {

                if(v->pq < 8 || v->dquantfrm) { // table 59

                    v->s.esc3_level_length = get_bits(gb, 3);

                    if(!v->s.esc3_level_length)

                        v->s.esc3_level_length = get_bits(gb, 2) + 8;

                } else { //table 60

                    v->s.esc3_level_length = get_unary(gb, 1, 6) + 2;

                }

                v->s.esc3_run_length = 3 + get_bits(gb, 2);

            }

            run = get_bits(gb, v->s.esc3_run_length);

            sign = get_bits1(gb);

            level = get_bits(gb, v->s.esc3_level_length);

            if(sign)

                level = -level;

        }

    }

    *last = lst;

    *skip = run;

    *value = level;

}


static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,

                            int trellis_node, int x, int y, int mbs_per_slice,

                            ProresThreadData *td)

{

    ProresContext *ctx = avctx->priv_data;

    int i, q, pq, xp, yp;

    const uint16_t *src;

    int slice_width_factor = av_log2(mbs_per_slice);

    int num_cblocks[MAX_PLANES], pwidth;

    int plane_factor[MAX_PLANES], is_chroma[MAX_PLANES];

    const int min_quant = ctx->profile_info->min_quant;

    const int max_quant = ctx->profile_info->max_quant;

    int error, bits, bits_limit;

    int mbs, prev, cur, new_score;

    int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];

    int overquant;

    uint16_t *qmat;

    int linesize[4], line_add;

    if (ctx->pictures_per_frame == 1)

        line_add = 0;

    else

        line_add = ctx->cur_picture_idx ^ !pic->top_field_first;

    mbs = x + mbs_per_slice;

    for (i = 0; i < ctx->num_planes; i++) {

        is_chroma[i]    = (i == 1 || i == 2);

        plane_factor[i] = slice_width_factor + 2;

        if (is_chroma[i])

            plane_factor[i] += ctx->chroma_factor - 3;

        if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {

            xp             = x << 4;

            yp             = y << 4;

            num_cblocks[i] = 4;

            pwidth         = avctx->width;

        } else {

            xp             = x << 3;

            yp             = y << 4;

            num_cblocks[i] = 2;

            pwidth         = avctx->width >> 1;

        }

        linesize[i] = pic->linesize[i] * ctx->pictures_per_frame;

        src = (const uint16_t*)(pic->data[i] + yp * linesize[i] +

                                line_add * pic->linesize[i]) + xp;

        if (i < 3) {

            get_slice_data(ctx, src, linesize[i], xp, yp,

                           pwidth, avctx->height / ctx->pictures_per_frame,

                           td->blocks[i], td->emu_buf,

                           mbs_per_slice, num_cblocks[i], is_chroma[i]);

        } else {

            get_alpha_data(ctx, src, linesize[i], xp, yp,

                           pwidth, avctx->height / ctx->pictures_per_frame,

                           td->blocks[i], mbs_per_slice, ctx->alpha_bits);

        }

    }

    for (q = min_quant; q < max_quant + 2; q++) {

        td->nodes[trellis_node + q].prev_node = -1;

        td->nodes[trellis_node + q].quant     = q;

    }

    // todo: maybe perform coarser quantising to fit into frame size when needed

    for (q = min_quant; q <= max_quant; q++) {

        bits  = 0;

        error = 0;

        for (i = 0; i < ctx->num_planes - !!ctx->alpha_bits; i++) {

            bits += estimate_slice_plane(ctx, &error, i,

                                         src, linesize[i],

                                         mbs_per_slice,

                                         num_cblocks[i], plane_factor[i],

                                         ctx->quants[q], td);

        }

        if (ctx->alpha_bits)

            bits += estimate_alpha_plane(ctx, &error, src, linesize[3],

                                         mbs_per_slice, q, td->blocks[3]);

        if (bits > 65000 * 8) {

            error = SCORE_LIMIT;

            break;

        }

        slice_bits[q]  = bits;

        slice_score[q] = error;

    }

    if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {

        slice_bits[max_quant + 1]  = slice_bits[max_quant];

        slice_score[max_quant + 1] = slice_score[max_quant] + 1;

        overquant = max_quant;

    } else {

        for (q = max_quant + 1; q < 128; q++) {

            bits  = 0;

            error = 0;

            if (q < MAX_STORED_Q) {

                qmat = ctx->quants[q];

            } else {

                qmat = td->custom_q;

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

                    qmat[i] = ctx->quant_mat[i] * q;

            }

            for (i = 0; i < ctx->num_planes - !!ctx->alpha_bits; i++) {

                bits += estimate_slice_plane(ctx, &error, i,

                                             src, linesize[i],

                                             mbs_per_slice,

                                             num_cblocks[i], plane_factor[i],

                                             qmat, td);

            }

            if (ctx->alpha_bits)

                bits += estimate_alpha_plane(ctx, &error, src, linesize[3],

                                             mbs_per_slice, q, td->blocks[3]);

            if (bits <= ctx->bits_per_mb * mbs_per_slice)

                break;

        }

        slice_bits[max_quant + 1]  = bits;

        slice_score[max_quant + 1] = error;

        overquant = q;

    }

    td->nodes[trellis_node + max_quant + 1].quant = overquant;

    bits_limit = mbs * ctx->bits_per_mb;

    for (pq = min_quant; pq < max_quant + 2; pq++) {

        prev = trellis_node - TRELLIS_WIDTH + pq;

        for (q = min_quant; q < max_quant + 2; q++) {

            cur = trellis_node + q;

            bits  = td->nodes[prev].bits + slice_bits[q];

            error = slice_score[q];

            if (bits > bits_limit)

                error = SCORE_LIMIT;

            if (td->nodes[prev].score < SCORE_LIMIT && error < SCORE_LIMIT)

                new_score = td->nodes[prev].score + error;

            else

                new_score = SCORE_LIMIT;

            if (td->nodes[cur].prev_node == -1 ||

                td->nodes[cur].score >= new_score) {

                td->nodes[cur].bits      = bits;

                td->nodes[cur].score     = new_score;

                td->nodes[cur].prev_node = prev;

            }

        }

    }

    error = td->nodes[trellis_node + min_quant].score;

    pq    = trellis_node + min_quant;

    for (q = min_quant + 1; q < max_quant + 2; q++) {

        if (td->nodes[trellis_node + q].score <= error) {

            error = td->nodes[trellis_node + q].score;

            pq    = trellis_node + q;

        }

    }

    return pq;

}


static void process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eof)

{

    int i;

    int repeating = 0;

    AVPacket avpkt;

    if (ist->next_dts == AV_NOPTS_VALUE)

        ist->next_dts = ist->last_dts;

    if (!pkt) {

        /* EOF handling */

        av_init_packet(&avpkt);

        avpkt.data = NULL;

        avpkt.size = 0;

    } else {

        avpkt = *pkt;

    }

    if (pkt && pkt->dts != AV_NOPTS_VALUE)

        ist->next_dts = ist->last_dts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);

    // while we have more to decode or while the decoder did output something on EOF

    while (ist->decoding_needed && (!pkt || avpkt.size > 0)) {

        int ret = 0;

        int got_output = 0;

        if (!repeating)

            ist->last_dts = ist->next_dts;

        switch (ist->dec_ctx->codec_type) {

        case AVMEDIA_TYPE_AUDIO:

            ret = decode_audio    (ist, repeating ? NULL : &avpkt, &got_output);

            break;

        case AVMEDIA_TYPE_VIDEO:

            ret = decode_video    (ist, repeating ? NULL : &avpkt, &got_output);

            if (repeating && !got_output)

                ;

            else if (pkt && pkt->duration)

                ist->next_dts += av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);

            else if (ist->st->avg_frame_rate.num)

                ist->next_dts += av_rescale_q(1, av_inv_q(ist->st->avg_frame_rate),

                                              AV_TIME_BASE_Q);

            else if (ist->dec_ctx->framerate.num != 0) {

                int ticks      = ist->st->parser ? ist->st->parser->repeat_pict + 1 :

                                                   ist->dec_ctx->ticks_per_frame;

                ist->next_dts += av_rescale_q(ticks, ist->dec_ctx->framerate, AV_TIME_BASE_Q);

            }

            break;

        case AVMEDIA_TYPE_SUBTITLE:

            if (repeating)

                break;

            ret = transcode_subtitles(ist, &avpkt, &got_output);

            break;

        default:

            return;

        }

        if (ret < 0) {

            av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n",

                   ist->file_index, ist->st->index);

            if (exit_on_error)

                exit_program(1);

            break;

        }

        if (!got_output)

            break;

        repeating = 1;

    }

    /* after flushing, send an EOF on all the filter inputs attached to the stream */

    /* except when looping we need to flush but not to send an EOF */

    if (!pkt && ist->decoding_needed && !no_eof) {

        int ret = send_filter_eof(ist);

        if (ret < 0) {

            av_log(NULL, AV_LOG_FATAL, "Error marking filters as finished\n");

            exit_program(1);

        }

    }

    /* handle stream copy */

    if (!ist->decoding_needed) {

        ist->last_dts = ist->next_dts;

        switch (ist->dec_ctx->codec_type) {

        case AVMEDIA_TYPE_AUDIO:

            ist->next_dts += ((int64_t)AV_TIME_BASE * ist->dec_ctx->frame_size) /

                             ist->dec_ctx->sample_rate;

            break;

        case AVMEDIA_TYPE_VIDEO:

            if (ist->dec_ctx->framerate.num != 0) {

                int ticks = ist->st->parser ? ist->st->parser->repeat_pict + 1 : ist->dec_ctx->ticks_per_frame;

                ist->next_dts += ((int64_t)AV_TIME_BASE *

                                  ist->dec_ctx->framerate.den * ticks) /

                                  ist->dec_ctx->framerate.num;

            }

            break;

        }

    }

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

        OutputStream *ost = output_streams[i];

        if (!check_output_constraints(ist, ost) || ost->encoding_needed)

            continue;

        do_streamcopy(ist, ost, pkt);

    }

    return;

}


static int adx_decode_header(AVCodecContext *avctx,const unsigned char *buf,size_t bufsize)

{

	int offset;

	int channels,freq,size;

	offset = is_adx(buf,bufsize);

	if (offset==0) return 0;

	channels = buf[7];

	freq = read_long(buf+8);

	size = read_long(buf+12);

//	printf("freq=%d ch=%d\n",freq,channels);

	avctx->sample_rate = freq;

	avctx->channels = channels;

	avctx->bit_rate = freq*channels*18*8/32;

//	avctx->frame_size = 18*channels;

	return offset;

}


uint32_t pci_default_read_config(PCIDevice *d,

                                 uint32_t address, int len)

{

    uint32_t val;

    switch(len) {

    case 1:

        val = d->config[address];

        break;

    case 2:

        val = le16_to_cpu(*(uint16_t *)(d->config + address));

        break;

    default:

    case 4:

        val = le32_to_cpu(*(uint32_t *)(d->config + address));

        break;

    }

    return val;

}


static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp)

{

    const QDictEntry *ent;

    int has_exec_key = 0;

    QDict *input_dict;

    if (qobject_type(input_obj) != QTYPE_QDICT) {

        error_set(errp, QERR_QMP_BAD_INPUT_OBJECT, "object");

        return NULL;

    }

    input_dict = qobject_to_qdict(input_obj);

    for (ent = qdict_first(input_dict); ent; ent = qdict_next(input_dict, ent)){

        const char *arg_name = qdict_entry_key(ent);

        const QObject *arg_obj = qdict_entry_value(ent);

        if (!strcmp(arg_name, "execute")) {

            if (qobject_type(arg_obj) != QTYPE_QSTRING) {

                error_set(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER,

                          "execute", "string");

                return NULL;

            }

            has_exec_key = 1;

        } else if (!strcmp(arg_name, "arguments")) {

            if (qobject_type(arg_obj) != QTYPE_QDICT) {

                error_set(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER,

                          "arguments", "object");

                return NULL;

            }

        } else {

            error_set(errp, QERR_QMP_EXTRA_MEMBER, arg_name);

            return NULL;

        }

    }

    if (!has_exec_key) {

        error_set(errp, QERR_QMP_BAD_INPUT_OBJECT, "execute");

        return NULL;

    }

    return input_dict;

}


static void vmxnet3_rx_need_csum_calculate(struct NetRxPkt *pkt,

                                           const void *pkt_data,

                                           size_t pkt_len)

{

    struct virtio_net_hdr *vhdr;

    bool isip4, isip6, istcp, isudp;

    uint8_t *data;

    int len;

    if (!net_rx_pkt_has_virt_hdr(pkt)) {

        return;

    }

    vhdr = net_rx_pkt_get_vhdr(pkt);

    if (!VMXNET_FLAG_IS_SET(vhdr->flags, VIRTIO_NET_HDR_F_NEEDS_CSUM)) {

        return;

    }

    net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);

    if (!(isip4 || isip6) || !(istcp || isudp)) {

        return;

    }

    vmxnet3_dump_virt_hdr(vhdr);

    /* Validate packet len: csum_start + scum_offset + length of csum field */

    if (pkt_len < (vhdr->csum_start + vhdr->csum_offset + 2)) {

        VMW_PKPRN("packet len:%zu < csum_start(%d) + csum_offset(%d) + 2, "

                  "cannot calculate checksum",

                  pkt_len, vhdr->csum_start, vhdr->csum_offset);

        return;

    }

    data = (uint8_t *)pkt_data + vhdr->csum_start;

    len = pkt_len - vhdr->csum_start;

    /* Put the checksum obtained into the packet */

    stw_be_p(data + vhdr->csum_offset, net_raw_checksum(data, len));

    vhdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;

    vhdr->flags |= VIRTIO_NET_HDR_F_DATA_VALID;

}


int ff_ps_apply(AVCodecContext *avctx, PSContext *ps, float L[2][38][64], float R[2][38][64], int top)

{

    float Lbuf[91][32][2];

    float Rbuf[91][32][2];

    const int len = 32;

    int is34 = ps->is34bands;

    top += NR_BANDS[is34] - 64;

    memset(ps->delay+top, 0, (NR_BANDS[is34] - top)*sizeof(ps->delay[0]));

    if (top < NR_ALLPASS_BANDS[is34])

        memset(ps->ap_delay + top, 0, (NR_ALLPASS_BANDS[is34] - top)*sizeof(ps->ap_delay[0]));

    hybrid_analysis(Lbuf, ps->in_buf, L, is34, len);

    decorrelation(ps, Rbuf, Lbuf, is34);

    stereo_processing(ps, Lbuf, Rbuf, is34);

    hybrid_synthesis(L, Lbuf, is34, len);

    hybrid_synthesis(R, Rbuf, is34, len);

    return 0;

}


static void bl_intrp(EVRCContext *e, float *ex, float delay)

{

    float *f;

    int offset, i, coef_idx;

    int16_t t;

    offset = lrintf(fabs(delay));

    t = (offset - delay + 0.5) * 8.0 + 0.5;

    if (t == 8) {

        t = 0;

        offset--;

    }

    f = ex - offset - 8;

    coef_idx = t * (2 * 8 + 1);

    ex[0] = 0.0;

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

        ex[0] += e->interpolation_coeffs[coef_idx + i] * f[i];

}


static av_always_inline void fic_idct(int16_t *blk, int step, int shift, int rnd)

{

    const int t0 =  27246 * blk[3 * step] + 18405 * blk[5 * step];

    const int t1 =  27246 * blk[5 * step] - 18405 * blk[3 * step];

    const int t2 =   6393 * blk[7 * step] + 32139 * blk[1 * step];

    const int t3 =   6393 * blk[1 * step] - 32139 * blk[7 * step];

    const unsigned t4 = 5793U * (t2 + t0 + 0x800 >> 12);

    const unsigned t5 = 5793U * (t3 + t1 + 0x800 >> 12);

    const unsigned t6 = t2 - t0;

    const unsigned t7 = t3 - t1;

    const unsigned t8 =  17734 * blk[2 * step] - 42813 * blk[6 * step];

    const unsigned t9 =  17734 * blk[6 * step] + 42814 * blk[2 * step];

    const unsigned tA = (blk[0 * step] - blk[4 * step]) * 32768 + rnd;

    const unsigned tB = (blk[0 * step] + blk[4 * step]) * 32768 + rnd;

    blk[0 * step] = (int)(  t4       + t9 + tB) >> shift;

    blk[1 * step] = (int)(  t6 + t7  + t8 + tA) >> shift;

    blk[2 * step] = (int)(  t6 - t7  - t8 + tA) >> shift;

    blk[3 * step] = (int)(  t5       - t9 + tB) >> shift;

    blk[4 * step] = (int)( -t5       - t9 + tB) >> shift;

    blk[5 * step] = (int)(-(t6 - t7) - t8 + tA) >> shift;

    blk[6 * step] = (int)(-(t6 + t7) + t8 + tA) >> shift;

    blk[7 * step] = (int)( -t4       + t9 + tB) >> shift;

}


static int qemu_rdma_alloc_pd_cq(RDMAContext *rdma)

{

    /* allocate pd */

    rdma->pd = ibv_alloc_pd(rdma->verbs);

    if (!rdma->pd) {

        fprintf(stderr, "failed to allocate protection domain\n");

        return -1;

    }

    /* create completion channel */

    rdma->comp_channel = ibv_create_comp_channel(rdma->verbs);

    if (!rdma->comp_channel) {

        fprintf(stderr, "failed to allocate completion channel\n");

        goto err_alloc_pd_cq;

    }

    /*

     * Completion queue can be filled by both read and write work requests,

     * so must reflect the sum of both possible queue sizes.

     */

    rdma->cq = ibv_create_cq(rdma->verbs, (RDMA_SIGNALED_SEND_MAX * 3),

            NULL, rdma->comp_channel, 0);

    if (!rdma->cq) {

        fprintf(stderr, "failed to allocate completion queue\n");

        goto err_alloc_pd_cq;

    }

    return 0;

err_alloc_pd_cq:

    if (rdma->pd) {

        ibv_dealloc_pd(rdma->pd);

    }

    if (rdma->comp_channel) {

        ibv_destroy_comp_channel(rdma->comp_channel);

    }

    rdma->pd = NULL;

    rdma->comp_channel = NULL;

    return -1;

}


static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj,

                                     Error **errp)

{

    QObjectInputVisitor *qiv = to_qiv(v);

    QObject *qobj = qobject_input_get_object(qiv, name, true, errp);

    QInt *qint;

    if (!qobj) {

        return;

    }

    qint = qobject_to_qint(qobj);

    if (!qint) {

        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",

                   "integer");

        return;

    }

    *obj = qint_get_int(qint);

}


static void xlnx_zynqmp_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);
    dc->props = xlnx_zynqmp_props;
    dc->realize = xlnx_zynqmp_realize;
}


static target_ulong h_send_logical_lan(CPUPPCState *env, sPAPREnvironment *spapr,

                                       target_ulong opcode, target_ulong *args)

{

    target_ulong reg = args[0];

    target_ulong *bufs = args + 1;

    target_ulong continue_token = args[7];

    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);

    VIOsPAPRVLANDevice *dev = (VIOsPAPRVLANDevice *)sdev;

    unsigned total_len;

    uint8_t *lbuf, *p;

    int i, nbufs;

    int ret;

    dprintf("H_SEND_LOGICAL_LAN(0x" TARGET_FMT_lx ", <bufs>, 0x"

            TARGET_FMT_lx ")\n", reg, continue_token);

    if (!sdev) {

        return H_PARAMETER;

    }

    dprintf("rxbufs = %d\n", dev->rx_bufs);

    if (!dev->isopen) {

        return H_DROPPED;

    }

    if (continue_token) {

        return H_HARDWARE; /* FIXME actually handle this */

    }

    total_len = 0;

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

        dprintf("   buf desc: 0x" TARGET_FMT_lx "\n", bufs[i]);

        if (!(bufs[i] & VLAN_BD_VALID)) {

            break;

        }

        total_len += VLAN_BD_LEN(bufs[i]);

    }

    nbufs = i;

    dprintf("h_send_logical_lan() %d buffers, total length 0x%x\n",

            nbufs, total_len);

    if (total_len == 0) {

        return H_SUCCESS;

    }

    if (total_len > MAX_PACKET_SIZE) {

        /* Don't let the guest force too large an allocation */

        return H_RESOURCE;

    }

    lbuf = alloca(total_len);

    p = lbuf;

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

        ret = spapr_tce_dma_read(sdev, VLAN_BD_ADDR(bufs[i]),

                                 p, VLAN_BD_LEN(bufs[i]));

        if (ret < 0) {

            return ret;

        }

        p += VLAN_BD_LEN(bufs[i]);

    }

    qemu_send_packet(&dev->nic->nc, lbuf, total_len);

    return H_SUCCESS;

}


static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t size)

{

    VirtIONet *n = qemu_get_nic_opaque(nc);

    VirtIONetQueue *q = virtio_net_get_subqueue(nc);

    VirtIODevice *vdev = VIRTIO_DEVICE(n);

    struct iovec mhdr_sg[VIRTQUEUE_MAX_SIZE];

    struct virtio_net_hdr_mrg_rxbuf mhdr;

    unsigned mhdr_cnt = 0;

    size_t offset, i, guest_offset;

    if (!virtio_net_can_receive(nc)) {

        return -1;

    }

    /* hdr_len refers to the header we supply to the guest */

    if (!virtio_net_has_buffers(q, size + n->guest_hdr_len - n->host_hdr_len)) {

        return 0;

    }

    if (!receive_filter(n, buf, size))

        return size;

    offset = i = 0;

    while (offset < size) {

        VirtQueueElement elem;

        int len, total;

        const struct iovec *sg = elem.in_sg;

        total = 0;

        if (virtqueue_pop(q->rx_vq, &elem) == 0) {

            if (i == 0)

                return -1;

            error_report("virtio-net unexpected empty queue: "

                         "i %zd mergeable %d offset %zd, size %zd, "

                         "guest hdr len %zd, host hdr len %zd "

                         "guest features 0x%" PRIx64,

                         i, n->mergeable_rx_bufs, offset, size,

                         n->guest_hdr_len, n->host_hdr_len,

                         vdev->guest_features);

            exit(1);

        }

        if (elem.in_num < 1) {

            error_report("virtio-net receive queue contains no in buffers");

            exit(1);

        }

        if (i == 0) {

            assert(offset == 0);

            if (n->mergeable_rx_bufs) {

                mhdr_cnt = iov_copy(mhdr_sg, ARRAY_SIZE(mhdr_sg),

                                    sg, elem.in_num,

                                    offsetof(typeof(mhdr), num_buffers),

                                    sizeof(mhdr.num_buffers));

            }

            receive_header(n, sg, elem.in_num, buf, size);

            offset = n->host_hdr_len;

            total += n->guest_hdr_len;

            guest_offset = n->guest_hdr_len;

        } else {

            guest_offset = 0;

        }

        /* copy in packet.  ugh */

        len = iov_from_buf(sg, elem.in_num, guest_offset,

                           buf + offset, size - offset);

        total += len;

        offset += len;

        /* If buffers can't be merged, at this point we

         * must have consumed the complete packet.

         * Otherwise, drop it. */

        if (!n->mergeable_rx_bufs && offset < size) {

#if 0

            error_report("virtio-net truncated non-mergeable packet: "

                         "i %zd mergeable %d offset %zd, size %zd, "

                         "guest hdr len %zd, host hdr len %zd",

                         i, n->mergeable_rx_bufs,

                         offset, size, n->guest_hdr_len, n->host_hdr_len);

#endif

            return size;

        }

        /* signal other side */

        virtqueue_fill(q->rx_vq, &elem, total, i++);

    }

    if (mhdr_cnt) {

        virtio_stw_p(vdev, &mhdr.num_buffers, i);

        iov_from_buf(mhdr_sg, mhdr_cnt,

                     0,

                     &mhdr.num_buffers, sizeof mhdr.num_buffers);

    }

    virtqueue_flush(q->rx_vq, i);

    virtio_notify(vdev, q->rx_vq);

    return size;

}


static int read_sm_data(AVFormatContext *s, AVIOContext *bc, AVPacket *pkt, int is_meta, int64_t maxpos)

{

    int count = ffio_read_varlen(bc);

    int skip_start = 0;

    int skip_end = 0;

    int channels = 0;

    int64_t channel_layout = 0;

    int sample_rate = 0;

    int width = 0;

    int height = 0;

    int i, ret;

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

        uint8_t name[256], str_value[256], type_str[256];

        int value;

        if (avio_tell(bc) >= maxpos)

            return AVERROR_INVALIDDATA;

        ret = get_str(bc, name, sizeof(name));

        if (ret < 0) {

            av_log(s, AV_LOG_ERROR, "get_str failed while reading sm data\n");

            return ret;

        }

        value = get_s(bc);

        if (value == -1) {

            get_str(bc, str_value, sizeof(str_value));

            av_log(s, AV_LOG_WARNING, "Unknown string %s / %s\n", name, str_value);

        } else if (value == -2) {

            uint8_t *dst = NULL;

            int64_t v64, value_len;

            get_str(bc, type_str, sizeof(type_str));

            value_len = ffio_read_varlen(bc);

            if (avio_tell(bc) + value_len >= maxpos)

                return AVERROR_INVALIDDATA;

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

                dst = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, value_len);

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

                dst = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, value_len);

            } else if (sscanf(name, "CodecSpecificSide%"SCNd64"", &v64) == 1) {

                dst = av_packet_new_side_data(pkt, AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, value_len + 8);

                if(!dst)

                    return AVERROR(ENOMEM);

                AV_WB64(dst, v64);

                dst += 8;

            } else if (!strcmp(name, "ChannelLayout") && value_len == 8) {

                channel_layout = avio_rl64(bc);

                continue;

            } else {

                av_log(s, AV_LOG_WARNING, "Unknown data %s / %s\n", name, type_str);

                avio_skip(bc, value_len);

                continue;

            }

            if(!dst)

                return AVERROR(ENOMEM);

            avio_read(bc, dst, value_len);

        } else if (value == -3) {

            value = get_s(bc);

        } else if (value == -4) {

            value = ffio_read_varlen(bc);

        } else if (value < -4) {

            get_s(bc);

        } else {

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

                skip_start = value;

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

                skip_end = value;

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

                channels = value;

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

                sample_rate = value;

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

                width = value;

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

                height = value;

            } else {

                av_log(s, AV_LOG_WARNING, "Unknown integer %s\n", name);

            }

        }

    }

    if (channels || channel_layout || sample_rate || width || height) {

        uint8_t *dst = av_packet_new_side_data(pkt, AV_PKT_DATA_PARAM_CHANGE, 28);

        if (!dst)

            return AVERROR(ENOMEM);

        bytestream_put_le32(&dst,

                            AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT*(!!channels) +

                            AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT*(!!channel_layout) +

                            AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE*(!!sample_rate) +

                            AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS*(!!(width|height))

                           );

        if (channels)

            bytestream_put_le32(&dst, channels);

        if (channel_layout)

            bytestream_put_le64(&dst, channel_layout);

        if (sample_rate)

            bytestream_put_le32(&dst, sample_rate);

        if (width || height){

            bytestream_put_le32(&dst, width);

            bytestream_put_le32(&dst, height);

        }

    }

    if (skip_start || skip_end) {

        uint8_t *dst = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10);

        if (!dst)

            return AVERROR(ENOMEM);

        AV_WL32(dst, skip_start);

        AV_WL32(dst+4, skip_end);

    }

    return 0;

}


static uint32_t epic_decode_pixel_pred(ePICContext *dc, int x, int y,
                                       const uint32_t *curr_row,
                                       const uint32_t *above_row)
{
    uint32_t N, W, NW, pred;
    unsigned delta;
    int GN, GW, GNW, R, G, B;
    if (x && y) {
        W  = curr_row[x  - 1];
        N  = above_row[x];
        NW = above_row[x - 1];
        GN  = (N  >> G_shift) & 0xFF;
        GW  = (W  >> G_shift) & 0xFF;
        GNW = (NW >> G_shift) & 0xFF;
        G = epic_decode_component_pred(dc, GN, GW, GNW);
        R = G + epic_decode_component_pred(dc,
                                           ((N  >> R_shift) & 0xFF) - GN,
                                           ((W  >> R_shift) & 0xFF) - GW,
                                           ((NW >> R_shift) & 0xFF) - GNW);
        B = G + epic_decode_component_pred(dc,
                                           ((N  >> B_shift) & 0xFF) - GN,
                                           ((W  >> B_shift) & 0xFF) - GW,
                                           ((NW >> B_shift) & 0xFF) - GNW);
    } else {
        if (x)
            pred = curr_row[x - 1];
        else
            pred = above_row[x];
        delta = ff_els_decode_unsigned(&dc->els_ctx, &dc->unsigned_rung);
        R     = ((pred >> R_shift) & 0xFF) - TOSIGNED(delta);
        delta = ff_els_decode_unsigned(&dc->els_ctx, &dc->unsigned_rung);
        G     = ((pred >> G_shift) & 0xFF) - TOSIGNED(delta);
        delta = ff_els_decode_unsigned(&dc->els_ctx, &dc->unsigned_rung);
        B     = ((pred >> B_shift) & 0xFF) - TOSIGNED(delta);
    return (R << R_shift) | (G << G_shift) | (B << B_shift);


static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *prod_name)

{

    int fd = -1, ret;

    USBDevice *d = NULL;

    USBHostDevice *dev;

    struct usbdevfs_connectinfo ci;

    char buf[1024];

    printf("husb: open device %d.%d\n", bus_num, addr);

    if (!usb_host_device_path) {

        perror("husb: USB Host Device Path not set");

        goto fail;

    }

    snprintf(buf, sizeof(buf), "%s/%03d/%03d", usb_host_device_path,

             bus_num, addr);

    fd = open(buf, O_RDWR | O_NONBLOCK);

    if (fd < 0) {

        perror(buf);

        goto fail;

    }

    dprintf("husb: opened %s\n", buf);

    d = usb_create(NULL /* FIXME */, "USB Host Device");

    dev = DO_UPCAST(USBHostDevice, dev, d);

    dev->bus_num = bus_num;

    dev->addr = addr;

    dev->fd = fd;

    /* read the device description */

    dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));

    if (dev->descr_len <= 0) {

        perror("husb: reading device data failed");

        goto fail;

    }

#ifdef DEBUG

    {

        int x;

        printf("=== begin dumping device descriptor data ===\n");

        for (x = 0; x < dev->descr_len; x++)

            printf("%02x ", dev->descr[x]);

        printf("\n=== end dumping device descriptor data ===\n");

    }

#endif

    /*

     * Initial configuration is -1 which makes us claim first

     * available config. We used to start with 1, which does not

     * always work. I've seen devices where first config starts

     * with 2.

     */

    if (!usb_host_claim_interfaces(dev, -1))

        goto fail;

    ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);

    if (ret < 0) {

        perror("usb_host_device_open: USBDEVFS_CONNECTINFO");

        goto fail;

    }

    printf("husb: grabbed usb device %d.%d\n", bus_num, addr);

    ret = usb_linux_update_endp_table(dev);

    if (ret)

        goto fail;

    if (ci.slow)

        dev->dev.speed = USB_SPEED_LOW;

    else

        dev->dev.speed = USB_SPEED_HIGH;

    if (!prod_name || prod_name[0] == '\0')

        snprintf(dev->dev.devname, sizeof(dev->dev.devname),

                 "host:%d.%d", bus_num, addr);

    else

        pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),

                prod_name);

    /* USB devio uses 'write' flag to check for async completions */

    qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);

    hostdev_link(dev);

    qdev_init(&d->qdev);

    return (USBDevice *) dev;

fail:

    if (d)

        qdev_free(&d->qdev);

    if (fd != -1)

        close(fd);

    return NULL;

}


static int vp9_decode_frame(AVCodecContext *avctx, void *frame,

                            int *got_frame, AVPacket *pkt)

{

    const uint8_t *data = pkt->data;

    int size = pkt->size;

    VP9Context *s = avctx->priv_data;

    int ret, i, j, ref;

    int retain_segmap_ref = s->s.frames[REF_FRAME_SEGMAP].segmentation_map &&

                            (!s->s.h.segmentation.enabled || !s->s.h.segmentation.update_map);

    AVFrame *f;

    if ((ret = decode_frame_header(avctx, data, size, &ref)) < 0) {

        return ret;

    } else if (ret == 0) {

        if (!s->s.refs[ref].f->buf[0]) {

            av_log(avctx, AV_LOG_ERROR, "Requested reference %d not available\n", ref);

            return AVERROR_INVALIDDATA;

        }

        if ((ret = av_frame_ref(frame, s->s.refs[ref].f)) < 0)

            return ret;

        ((AVFrame *)frame)->pts = pkt->pts;

#if FF_API_PKT_PTS

FF_DISABLE_DEPRECATION_WARNINGS

        ((AVFrame *)frame)->pkt_pts = pkt->pts;

FF_ENABLE_DEPRECATION_WARNINGS

#endif

        ((AVFrame *)frame)->pkt_dts = pkt->dts;

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

            if (s->next_refs[i].f->buf[0])

                ff_thread_release_buffer(avctx, &s->next_refs[i]);

            if (s->s.refs[i].f->buf[0] &&

                (ret = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i])) < 0)

                return ret;

        }

        *got_frame = 1;

        return pkt->size;

    }

    data += ret;

    size -= ret;

    if (!retain_segmap_ref || s->s.h.keyframe || s->s.h.intraonly) {

        if (s->s.frames[REF_FRAME_SEGMAP].tf.f->buf[0])

            vp9_frame_unref(avctx, &s->s.frames[REF_FRAME_SEGMAP]);

        if (!s->s.h.keyframe && !s->s.h.intraonly && !s->s.h.errorres && s->s.frames[CUR_FRAME].tf.f->buf[0] &&

            (ret = vp9_frame_ref(avctx, &s->s.frames[REF_FRAME_SEGMAP], &s->s.frames[CUR_FRAME])) < 0)

            return ret;

    }

    if (s->s.frames[REF_FRAME_MVPAIR].tf.f->buf[0])

        vp9_frame_unref(avctx, &s->s.frames[REF_FRAME_MVPAIR]);

    if (!s->s.h.intraonly && !s->s.h.keyframe && !s->s.h.errorres && s->s.frames[CUR_FRAME].tf.f->buf[0] &&

        (ret = vp9_frame_ref(avctx, &s->s.frames[REF_FRAME_MVPAIR], &s->s.frames[CUR_FRAME])) < 0)

        return ret;

    if (s->s.frames[CUR_FRAME].tf.f->buf[0])

        vp9_frame_unref(avctx, &s->s.frames[CUR_FRAME]);

    if ((ret = vp9_frame_alloc(avctx, &s->s.frames[CUR_FRAME])) < 0)

        return ret;

    f = s->s.frames[CUR_FRAME].tf.f;

    f->key_frame = s->s.h.keyframe;

    f->pict_type = (s->s.h.keyframe || s->s.h.intraonly) ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;

    if (s->s.frames[REF_FRAME_SEGMAP].tf.f->buf[0] &&

        (s->s.frames[REF_FRAME_MVPAIR].tf.f->width  != s->s.frames[CUR_FRAME].tf.f->width ||

         s->s.frames[REF_FRAME_MVPAIR].tf.f->height != s->s.frames[CUR_FRAME].tf.f->height)) {

        vp9_frame_unref(avctx, &s->s.frames[REF_FRAME_SEGMAP]);

    }

    // ref frame setup

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

        if (s->next_refs[i].f->buf[0])

            ff_thread_release_buffer(avctx, &s->next_refs[i]);

        if (s->s.h.refreshrefmask & (1 << i)) {

            ret = ff_thread_ref_frame(&s->next_refs[i], &s->s.frames[CUR_FRAME].tf);

        } else if (s->s.refs[i].f->buf[0]) {

            ret = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i]);

        }

        if (ret < 0)

            return ret;

    }

    if (avctx->hwaccel) {

        ret = avctx->hwaccel->start_frame(avctx, NULL, 0);

        if (ret < 0)

            return ret;

        ret = avctx->hwaccel->decode_slice(avctx, pkt->data, pkt->size);

        if (ret < 0)

            return ret;

        ret = avctx->hwaccel->end_frame(avctx);

        if (ret < 0)

            return ret;

        goto finish;

    }

    // main tile decode loop

    memset(s->above_partition_ctx, 0, s->cols);

    memset(s->above_skip_ctx, 0, s->cols);

    if (s->s.h.keyframe || s->s.h.intraonly) {

        memset(s->above_mode_ctx, DC_PRED, s->cols * 2);

    } else {

        memset(s->above_mode_ctx, NEARESTMV, s->cols);

    }

    memset(s->above_y_nnz_ctx, 0, s->sb_cols * 16);

    memset(s->above_uv_nnz_ctx[0], 0, s->sb_cols * 16 >> s->ss_h);

    memset(s->above_uv_nnz_ctx[1], 0, s->sb_cols * 16 >> s->ss_h);

    memset(s->above_segpred_ctx, 0, s->cols);

    s->pass = s->s.frames[CUR_FRAME].uses_2pass =

        avctx->active_thread_type == FF_THREAD_FRAME && s->s.h.refreshctx && !s->s.h.parallelmode;

    if ((ret = update_block_buffers(avctx)) < 0) {

        av_log(avctx, AV_LOG_ERROR,

               "Failed to allocate block buffers\n");

        return ret;

    }

    if (s->s.h.refreshctx && s->s.h.parallelmode) {

        int j, k, l, m;

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

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

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

                    for (l = 0; l < 6; l++)

                        for (m = 0; m < 6; m++)

                            memcpy(s->prob_ctx[s->s.h.framectxid].coef[i][j][k][l][m],

                                   s->prob.coef[i][j][k][l][m], 3);

            if (s->s.h.txfmmode == i)

                break;

        }

        s->prob_ctx[s->s.h.framectxid].p = s->prob.p;

        ff_thread_finish_setup(avctx);

    } else if (!s->s.h.refreshctx) {

        ff_thread_finish_setup(avctx);

    }

#if HAVE_THREADS

    if (avctx->active_thread_type & FF_THREAD_SLICE) {

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

            atomic_store(&s->entries[i], 0);

    }

#endif

    do {

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

            s->td[i].b = s->td[i].b_base;

            s->td[i].block = s->td[i].block_base;

            s->td[i].uvblock[0] = s->td[i].uvblock_base[0];

            s->td[i].uvblock[1] = s->td[i].uvblock_base[1];

            s->td[i].eob = s->td[i].eob_base;

            s->td[i].uveob[0] = s->td[i].uveob_base[0];

            s->td[i].uveob[1] = s->td[i].uveob_base[1];

        }

#if HAVE_THREADS

        if (avctx->active_thread_type == FF_THREAD_SLICE) {

            int tile_row, tile_col;

            av_assert1(!s->pass);

            for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) {

                for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) {

                    int64_t tile_size;

                    if (tile_col == s->s.h.tiling.tile_cols - 1 &&

                        tile_row == s->s.h.tiling.tile_rows - 1) {

                        tile_size = size;

                    } else {

                        tile_size = AV_RB32(data);

                        data += 4;

                        size -= 4;

                    }

                    if (tile_size > size)

                        return AVERROR_INVALIDDATA;

                    ret = ff_vp56_init_range_decoder(&s->td[tile_col].c_b[tile_row], data, tile_size);

                    if (ret < 0)

                        return ret;

                    if (vp56_rac_get_prob_branchy(&s->td[tile_col].c_b[tile_row], 128)) // marker bit

                        return AVERROR_INVALIDDATA;

                    data += tile_size;

                    size -= tile_size;

                }

            }

            ff_slice_thread_execute_with_mainfunc(avctx, decode_tiles_mt, loopfilter_proc, s->td, NULL, s->s.h.tiling.tile_cols);

        } else

#endif

        {

            ret = decode_tiles(avctx, data, size);

            if (ret < 0)

                return ret;

        }

        // Sum all counts fields into td[0].counts for tile threading

        if (avctx->active_thread_type == FF_THREAD_SLICE)

            for (i = 1; i < s->s.h.tiling.tile_cols; i++)

                for (j = 0; j < sizeof(s->td[i].counts) / sizeof(unsigned); j++)

                    ((unsigned *)&s->td[0].counts)[j] += ((unsigned *)&s->td[i].counts)[j];

        if (s->pass < 2 && s->s.h.refreshctx && !s->s.h.parallelmode) {

            ff_vp9_adapt_probs(s);

            ff_thread_finish_setup(avctx);

        }

    } while (s->pass++ == 1);

    ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0);

finish:

    // ref frame setup

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

        if (s->s.refs[i].f->buf[0])

            ff_thread_release_buffer(avctx, &s->s.refs[i]);

        if (s->next_refs[i].f->buf[0] &&

            (ret = ff_thread_ref_frame(&s->s.refs[i], &s->next_refs[i])) < 0)

            return ret;

    }

    if (!s->s.h.invisible) {

        if ((ret = av_frame_ref(frame, s->s.frames[CUR_FRAME].tf.f)) < 0)

            return ret;

        *got_frame = 1;

    }

    return pkt->size;

}


static void ccid_card_vscard_send_msg(PassthruState *s,

        VSCMsgType type, uint32_t reader_id,

        const uint8_t *payload, uint32_t length)

{

    VSCMsgHeader scr_msg_header;

    scr_msg_header.type = htonl(type);

    scr_msg_header.reader_id = htonl(reader_id);

    scr_msg_header.length = htonl(length);

    qemu_chr_fe_write(s->cs, (uint8_t *)&scr_msg_header, sizeof(VSCMsgHeader));

    qemu_chr_fe_write(s->cs, payload, length);

}


static int kvmclock_post_load(void *opaque, int version_id)

{

    KVMClockState *s = opaque;

    struct kvm_clock_data data;

    data.clock = s->clock;

    data.flags = 0;

    return kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data);

}


static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)

{

    TCGReg datalo, datahi, addrlo, rbase;

    TCGReg addrhi __attribute__((unused));

    TCGMemOpIdx oi;

    TCGMemOp opc, s_bits;

#ifdef CONFIG_SOFTMMU

    int mem_index;

    tcg_insn_unit *label_ptr;

#endif

    datalo = *args++;

    datahi = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);

    addrlo = *args++;

    addrhi = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);

    oi = *args++;

    opc = get_memop(oi);

    s_bits = opc & MO_SIZE;

#ifdef CONFIG_SOFTMMU

    mem_index = get_mmuidx(oi);

    addrlo = tcg_out_tlb_read(s, s_bits, addrlo, addrhi, mem_index, false);

    /* Load a pointer into the current opcode w/conditional branch-link. */

    label_ptr = s->code_ptr;

    tcg_out_bc_noaddr(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);

    rbase = TCG_REG_R3;

#else  /* !CONFIG_SOFTMMU */

    rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;

    if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {

        tcg_out_ext32u(s, TCG_REG_TMP1, addrlo);

        addrlo = TCG_REG_TMP1;

    }

#endif

    if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {

        if (opc & MO_BSWAP) {

            tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));

            tcg_out32(s, STWBRX | SAB(datalo, rbase, addrlo));

            tcg_out32(s, STWBRX | SAB(datahi, rbase, TCG_REG_R0));

        } else if (rbase != 0) {

            tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));

            tcg_out32(s, STWX | SAB(datahi, rbase, addrlo));

            tcg_out32(s, STWX | SAB(datalo, rbase, TCG_REG_R0));

        } else {

            tcg_out32(s, STW | TAI(datahi, addrlo, 0));

            tcg_out32(s, STW | TAI(datalo, addrlo, 4));

        }

    } else {

        uint32_t insn = qemu_stx_opc[opc & (MO_BSWAP | MO_SIZE)];

        if (!HAVE_ISA_2_06 && insn == STDBRX) {

            tcg_out32(s, STWBRX | SAB(datalo, rbase, addrlo));

            tcg_out32(s, ADDI | TAI(TCG_REG_TMP1, addrlo, 4));

            tcg_out_shri64(s, TCG_REG_R0, datalo, 32);

            tcg_out32(s, STWBRX | SAB(TCG_REG_R0, rbase, TCG_REG_TMP1));

        } else {

            tcg_out32(s, insn | SAB(datalo, rbase, addrlo));

        }

    }

#ifdef CONFIG_SOFTMMU

    add_qemu_ldst_label(s, false, oi, datalo, datahi, addrlo, addrhi,

                        s->code_ptr, label_ptr);

#endif

}


static int decode_dvd_subtitles(AVSubtitle *sub_header,

                                const uint8_t *buf, int buf_size)

{

    int cmd_pos, pos, cmd, x1, y1, x2, y2, offset1, offset2, next_cmd_pos;

    int big_offsets, offset_size, is_8bit = 0;

    const uint8_t *yuv_palette = 0;

    uint8_t colormap[4], alpha[256];

    int date;

    int i;

    int is_menu = 0;

    if (buf_size < 10)

        return -1;

    sub_header->rects = NULL;

    sub_header->num_rects = 0;

    sub_header->format = 0;

    sub_header->start_display_time = 0;

    sub_header->end_display_time = 0;

    if (AV_RB16(buf) == 0) {   /* HD subpicture with 4-byte offsets */

        big_offsets = 1;

        offset_size = 4;

        cmd_pos = 6;

    } else {

        big_offsets = 0;

        offset_size = 2;

        cmd_pos = 2;

    }

    cmd_pos = READ_OFFSET(buf + cmd_pos);

    while ((cmd_pos + 2 + offset_size) < buf_size) {

        date = AV_RB16(buf + cmd_pos);

        next_cmd_pos = READ_OFFSET(buf + cmd_pos + 2);

        dprintf(NULL, "cmd_pos=0x%04x next=0x%04x date=%d\n",

                cmd_pos, next_cmd_pos, date);

        pos = cmd_pos + 2 + offset_size;

        offset1 = -1;

        offset2 = -1;

        x1 = y1 = x2 = y2 = 0;

        while (pos < buf_size) {

            cmd = buf[pos++];

            dprintf(NULL, "cmd=%02x\n", cmd);

            switch(cmd) {

            case 0x00:

                /* menu subpicture */

                is_menu = 1;

                break;

            case 0x01:

                /* set start date */

                sub_header->start_display_time = (date << 10) / 90;

                break;

            case 0x02:

                /* set end date */

                sub_header->end_display_time = (date << 10) / 90;

                break;

            case 0x03:

                /* set colormap */

                if ((buf_size - pos) < 2)

                    goto fail;

                colormap[3] = buf[pos] >> 4;

                colormap[2] = buf[pos] & 0x0f;

                colormap[1] = buf[pos + 1] >> 4;

                colormap[0] = buf[pos + 1] & 0x0f;

                pos += 2;

                break;

            case 0x04:

                /* set alpha */

                if ((buf_size - pos) < 2)

                    goto fail;

                alpha[3] = buf[pos] >> 4;

                alpha[2] = buf[pos] & 0x0f;

                alpha[1] = buf[pos + 1] >> 4;

                alpha[0] = buf[pos + 1] & 0x0f;

                pos += 2;

            dprintf(NULL, "alpha=%x%x%x%x\n", alpha[0],alpha[1],alpha[2],alpha[3]);

                break;

            case 0x05:

            case 0x85:

                if ((buf_size - pos) < 6)

                    goto fail;

                x1 = (buf[pos] << 4) | (buf[pos + 1] >> 4);

                x2 = ((buf[pos + 1] & 0x0f) << 8) | buf[pos + 2];

                y1 = (buf[pos + 3] << 4) | (buf[pos + 4] >> 4);

                y2 = ((buf[pos + 4] & 0x0f) << 8) | buf[pos + 5];

                if (cmd & 0x80)

                    is_8bit = 1;

                dprintf(NULL, "x1=%d x2=%d y1=%d y2=%d\n", x1, x2, y1, y2);

                pos += 6;

                break;

            case 0x06:

                if ((buf_size - pos) < 4)

                    goto fail;

                offset1 = AV_RB16(buf + pos);

                offset2 = AV_RB16(buf + pos + 2);

                dprintf(NULL, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2);

                pos += 4;

                break;

            case 0x86:

                if ((buf_size - pos) < 8)

                    goto fail;

                offset1 = AV_RB32(buf + pos);

                offset2 = AV_RB32(buf + pos + 4);

                dprintf(NULL, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2);

                pos += 8;

                break;

            case 0x83:

                /* HD set palette */

                if ((buf_size - pos) < 768)

                    goto fail;

                yuv_palette = buf + pos;

                pos += 768;

                break;

            case 0x84:

                /* HD set contrast (alpha) */

                if ((buf_size - pos) < 256)

                    goto fail;

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

                    alpha[i] = 0xFF - buf[pos+i];

                pos += 256;

                break;

            case 0xff:

                goto the_end;

            default:

                dprintf(NULL, "unrecognised subpicture command 0x%x\n", cmd);

                goto the_end;

            }

        }

    the_end:

        if (offset1 >= 0) {

            int w, h;

            uint8_t *bitmap;

            /* decode the bitmap */

            w = x2 - x1 + 1;

            if (w < 0)

                w = 0;

            h = y2 - y1;

            if (h < 0)

                h = 0;

            if (w > 0 && h > 0) {

                if (sub_header->rects != NULL) {

                    for (i = 0; i < sub_header->num_rects; i++) {

                        av_freep(&sub_header->rects[i]->pict.data[0]);

                        av_freep(&sub_header->rects[i]->pict.data[1]);

                        av_freep(&sub_header->rects[i]);

                    }

                    av_freep(&sub_header->rects);

                    sub_header->num_rects = 0;

                }

                bitmap = av_malloc(w * h);

                sub_header->rects = av_mallocz(sizeof(*sub_header->rects));

                sub_header->rects[0] = av_mallocz(sizeof(AVSubtitleRect));

                sub_header->num_rects = 1;

                sub_header->rects[0]->pict.data[0] = bitmap;

                decode_rle(bitmap, w * 2, w, (h + 1) / 2,

                           buf, offset1, buf_size, is_8bit);

                decode_rle(bitmap + w, w * 2, w, h / 2,

                           buf, offset2, buf_size, is_8bit);

                if (is_8bit) {

                    if (yuv_palette == 0)

                        goto fail;

                    sub_header->rects[0]->pict.data[1] = av_malloc(256 * 4);

                    sub_header->rects[0]->nb_colors = 256;

                    yuv_a_to_rgba(yuv_palette, alpha, (uint32_t*)sub_header->rects[0]->pict.data[1], 256);

                } else {

                    sub_header->rects[0]->pict.data[1] = av_malloc(4 * 4);

                    sub_header->rects[0]->nb_colors = 4;

                    guess_palette((uint32_t*)sub_header->rects[0]->pict.data[1],

                                  colormap, alpha, 0xffff00);

                }

                sub_header->rects[0]->x = x1;

                sub_header->rects[0]->y = y1;

                sub_header->rects[0]->w = w;

                sub_header->rects[0]->h = h;

                sub_header->rects[0]->type = SUBTITLE_BITMAP;

                sub_header->rects[0]->pict.linesize[0] = w;

            }

        }

        if (next_cmd_pos == cmd_pos)

            break;

        cmd_pos = next_cmd_pos;

    }

    if (sub_header->num_rects > 0)

        return is_menu;

 fail:

    if (sub_header->rects != NULL) {

        for (i = 0; i < sub_header->num_rects; i++) {

            av_freep(&sub_header->rects[i]->pict.data[0]);

            av_freep(&sub_header->rects[i]->pict.data[1]);

            av_freep(&sub_header->rects[i]);

        }

        av_freep(&sub_header->rects);

        sub_header->num_rects = 0;

    }

    return -1;

}


int ff_vaapi_render_picture(struct vaapi_context *vactx, VASurfaceID surface)
{
    VABufferID va_buffers[3];
    unsigned int n_va_buffers = 0;
    vaUnmapBuffer(vactx->display, vactx->pic_param_buf_id);
    va_buffers[n_va_buffers++] = vactx->pic_param_buf_id;
    if (vactx->iq_matrix_buf_id) {
        vaUnmapBuffer(vactx->display, vactx->iq_matrix_buf_id);
        va_buffers[n_va_buffers++] = vactx->iq_matrix_buf_id;
    }
    if (vactx->bitplane_buf_id) {
        vaUnmapBuffer(vactx->display, vactx->bitplane_buf_id);
        va_buffers[n_va_buffers++] = vactx->bitplane_buf_id;
    }
    if (vaBeginPicture(vactx->display, vactx->context_id,
                       surface) != VA_STATUS_SUCCESS)
        return -1;
    if (vaRenderPicture(vactx->display, vactx->context_id,
                        va_buffers, n_va_buffers) != VA_STATUS_SUCCESS)
        return -1;
    if (vaRenderPicture(vactx->display, vactx->context_id,
                        vactx->slice_buf_ids,
                        vactx->n_slice_buf_ids) != VA_STATUS_SUCCESS)
        return -1;
    if (vaEndPicture(vactx->display, vactx->context_id) != VA_STATUS_SUCCESS)
        return -1;
}


static av_cold int xcbgrab_read_header(AVFormatContext *s)

{

    XCBGrabContext *c = s->priv_data;

    int screen_num, ret;

    const xcb_setup_t *setup;

    char *host        = s->filename[0] ? s->filename : NULL;

    const char *opts  = strchr(s->filename, '+');

    if (opts) {

        sscanf(opts, "%d,%d", &c->x, &c->y);

        host = av_strdup(s->filename);

        host[opts - s->filename] = '\0';

    }

    c->conn = xcb_connect(host, &screen_num);

    if (opts)

        av_free(host);

    if ((ret = xcb_connection_has_error(c->conn))) {

        av_log(s, AV_LOG_ERROR, "Cannot open display %s, error %d.\n",

               s->filename[0] ? host : "default", ret);

        return AVERROR(EIO);

    }

    setup = xcb_get_setup(c->conn);

    c->screen = get_screen(setup, screen_num);

    if (!c->screen) {

        av_log(s, AV_LOG_ERROR, "The screen %d does not exist.\n",

               screen_num);

        xcbgrab_read_close(s);

        return AVERROR(EIO);

    }

    ret = create_stream(s);

    if (ret < 0) {

        xcbgrab_read_close(s);

        return ret;

    }

#if CONFIG_LIBXCB_SHM

    if ((c->has_shm = check_shm(c->conn)))

        c->segment = xcb_generate_id(c->conn);

#endif

#if CONFIG_LIBXCB_XFIXES

    if (c->draw_mouse) {

        if (!(c->draw_mouse = check_xfixes(c->conn))) {

            av_log(s, AV_LOG_WARNING,

                   "XFixes not available, cannot draw the mouse.\n");

        }

        if (c->bpp < 24) {

            avpriv_report_missing_feature(s, "%d bits per pixel screen",

                                          c->bpp);

            c->draw_mouse = 0;

        }

    }

#endif

    if (c->show_region)

        setup_window(s);

    return 0;

}


static int parse_pixel_format(AVCodecContext *avctx)
{
    DDSContext *ctx = avctx->priv_data;
    GetByteContext *gbc = &ctx->gbc;
    char buf[32];
    uint32_t flags, fourcc, gimp_tag;
    enum DDSDXGIFormat dxgi;
    int size, bpp, r, g, b, a;
    int alpha_exponent, ycocg_classic, ycocg_scaled, normal_map, array;
    /* Alternative DDS implementations use reserved1 as custom header. */
    bytestream2_skip(gbc, 4 * 3);
    gimp_tag = bytestream2_get_le32(gbc);
    alpha_exponent = gimp_tag == MKTAG('A', 'E', 'X', 'P');
    ycocg_classic  = gimp_tag == MKTAG('Y', 'C', 'G', '1');
    ycocg_scaled   = gimp_tag == MKTAG('Y', 'C', 'G', '2');
    bytestream2_skip(gbc, 4 * 7);
    /* Now the real DDPF starts. */
    size = bytestream2_get_le32(gbc);
    if (size != 32) {
        av_log(avctx, AV_LOG_ERROR, "Invalid pixel format header %d.\n", size);
        return AVERROR_INVALIDDATA;
    flags = bytestream2_get_le32(gbc);
    ctx->compressed = flags & DDPF_FOURCC;
    ctx->paletted   = flags & DDPF_PALETTE;
    normal_map      = flags & DDPF_NORMALMAP;
    fourcc = bytestream2_get_le32(gbc);
    bpp = bytestream2_get_le32(gbc); // rgbbitcount
    r   = bytestream2_get_le32(gbc); // rbitmask
    g   = bytestream2_get_le32(gbc); // gbitmask
    b   = bytestream2_get_le32(gbc); // bbitmask
    a   = bytestream2_get_le32(gbc); // abitmask
    bytestream2_skip(gbc, 4); // caps
    bytestream2_skip(gbc, 4); // caps2
    bytestream2_skip(gbc, 4); // caps3
    bytestream2_skip(gbc, 4); // caps4
    bytestream2_skip(gbc, 4); // reserved2
    av_get_codec_tag_string(buf, sizeof(buf), fourcc);
    av_log(avctx, AV_LOG_VERBOSE, "fourcc %s bpp %d "
           "r 0x%x g 0x%x b 0x%x a 0x%x\n", buf, bpp, r, g, b, a);
    if (gimp_tag) {
        av_get_codec_tag_string(buf, sizeof(buf), gimp_tag);
        av_log(avctx, AV_LOG_VERBOSE, "and GIMP-DDS tag %s\n", buf);
    if (ctx->compressed)
        avctx->pix_fmt = AV_PIX_FMT_RGBA;
    if (ctx->compressed) {
        switch (fourcc) {
        case MKTAG('D', 'X', 'T', '1'):
            ctx->tex_ratio = 8;
            ctx->tex_funct = ctx->texdsp.dxt1a_block;
            break;
        case MKTAG('D', 'X', 'T', '2'):
            ctx->tex_ratio = 16;
            ctx->tex_funct = ctx->texdsp.dxt2_block;
            break;
        case MKTAG('D', 'X', 'T', '3'):
            ctx->tex_ratio = 16;
            ctx->tex_funct = ctx->texdsp.dxt3_block;
            break;
        case MKTAG('D', 'X', 'T', '4'):
            ctx->tex_ratio = 16;
            ctx->tex_funct = ctx->texdsp.dxt4_block;
            break;
        case MKTAG('D', 'X', 'T', '5'):
            ctx->tex_ratio = 16;
            if (ycocg_scaled)
                ctx->tex_funct = ctx->texdsp.dxt5ys_block;
            else if (ycocg_classic)
                ctx->tex_funct = ctx->texdsp.dxt5y_block;
            else
                ctx->tex_funct = ctx->texdsp.dxt5_block;
            break;
        case MKTAG('R', 'X', 'G', 'B'):
            ctx->tex_ratio = 16;
            ctx->tex_funct = ctx->texdsp.dxt5_block;
            /* This format may be considered as a normal map,
             * but it is handled differently in a separate postproc. */
            ctx->postproc = DDS_SWIZZLE_RXGB;
            normal_map = 0;
            break;
        case MKTAG('A', 'T', 'I', '1'):
        case MKTAG('B', 'C', '4', 'U'):
            ctx->tex_ratio = 8;
            ctx->tex_funct = ctx->texdsp.rgtc1u_block;
            break;
        case MKTAG('B', 'C', '4', 'S'):
            ctx->tex_ratio = 8;
            ctx->tex_funct = ctx->texdsp.rgtc1s_block;
            break;
        case MKTAG('A', 'T', 'I', '2'):
            /* RGT2 variant with swapped R and G (3Dc)*/
            ctx->tex_ratio = 16;
            ctx->tex_funct = ctx->texdsp.dxn3dc_block;
            break;
        case MKTAG('B', 'C', '5', 'U'):
            ctx->tex_ratio = 16;
            ctx->tex_funct = ctx->texdsp.rgtc2u_block;
            break;
        case MKTAG('B', 'C', '5', 'S'):
            ctx->tex_ratio = 16;
            ctx->tex_funct = ctx->texdsp.rgtc2s_block;
            break;
        case MKTAG('U', 'Y', 'V', 'Y'):
            ctx->compressed = 0;
            avctx->pix_fmt = AV_PIX_FMT_UYVY422;
            break;
        case MKTAG('Y', 'U', 'Y', '2'):
            ctx->compressed = 0;
            avctx->pix_fmt = AV_PIX_FMT_YUYV422;
            break;
        case MKTAG('P', '8', ' ', ' '):
            /* ATI Palette8, same as normal palette */
            ctx->compressed = 0;
            ctx->paletted   = 1;
            avctx->pix_fmt  = AV_PIX_FMT_PAL8;
            break;
        case MKTAG('D', 'X', '1', '0'):
            /* DirectX 10 extra header */
            dxgi = bytestream2_get_le32(gbc);
            bytestream2_skip(gbc, 4); // resourceDimension
            bytestream2_skip(gbc, 4); // miscFlag
            array = bytestream2_get_le32(gbc);
            bytestream2_skip(gbc, 4); // miscFlag2
            if (array != 0)
                av_log(avctx, AV_LOG_VERBOSE,
                       "Found array of size %d (ignored).\n", array);
            /* Only BC[1-5] are actually compressed. */
            ctx->compressed = (dxgi >= 70) && (dxgi <= 84);
            av_log(avctx, AV_LOG_VERBOSE, "DXGI format %d.\n", dxgi);
            switch (dxgi) {
            /* RGB types. */
            case DXGI_FORMAT_R16G16B16A16_TYPELESS:
            case DXGI_FORMAT_R16G16B16A16_FLOAT:
            case DXGI_FORMAT_R16G16B16A16_UNORM:
            case DXGI_FORMAT_R16G16B16A16_UINT:
            case DXGI_FORMAT_R16G16B16A16_SNORM:
            case DXGI_FORMAT_R16G16B16A16_SINT:
                avctx->pix_fmt = AV_PIX_FMT_BGRA64;
                break;
            case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
                avctx->colorspace = AVCOL_SPC_RGB;
            case DXGI_FORMAT_R8G8B8A8_TYPELESS:
            case DXGI_FORMAT_R8G8B8A8_UNORM:
            case DXGI_FORMAT_R8G8B8A8_UINT:
            case DXGI_FORMAT_R8G8B8A8_SNORM:
            case DXGI_FORMAT_R8G8B8A8_SINT:
                avctx->pix_fmt = AV_PIX_FMT_BGRA;
                break;
            case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
                avctx->colorspace = AVCOL_SPC_RGB;
            case DXGI_FORMAT_B8G8R8A8_TYPELESS:
            case DXGI_FORMAT_B8G8R8A8_UNORM:
                avctx->pix_fmt = AV_PIX_FMT_RGBA;
                break;
            case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
                avctx->colorspace = AVCOL_SPC_RGB;
            case DXGI_FORMAT_B8G8R8X8_TYPELESS:
            case DXGI_FORMAT_B8G8R8X8_UNORM:
                avctx->pix_fmt = AV_PIX_FMT_RGBA; // opaque
                break;
            case DXGI_FORMAT_B5G6R5_UNORM:
                avctx->pix_fmt = AV_PIX_FMT_RGB565LE;
                break;
            /* Texture types. */
            case DXGI_FORMAT_BC1_UNORM_SRGB:
                avctx->colorspace = AVCOL_SPC_RGB;
            case DXGI_FORMAT_BC1_TYPELESS:
            case DXGI_FORMAT_BC1_UNORM:
                ctx->tex_ratio = 8;
                ctx->tex_funct = ctx->texdsp.dxt1a_block;
                break;
            case DXGI_FORMAT_BC2_UNORM_SRGB:
                avctx->colorspace = AVCOL_SPC_RGB;
            case DXGI_FORMAT_BC2_TYPELESS:
            case DXGI_FORMAT_BC2_UNORM:
                ctx->tex_ratio = 16;
                ctx->tex_funct = ctx->texdsp.dxt3_block;
                break;
            case DXGI_FORMAT_BC3_UNORM_SRGB:
                avctx->colorspace = AVCOL_SPC_RGB;
            case DXGI_FORMAT_BC3_TYPELESS:
            case DXGI_FORMAT_BC3_UNORM:
                ctx->tex_ratio = 16;
                ctx->tex_funct = ctx->texdsp.dxt5_block;
                break;
            case DXGI_FORMAT_BC4_TYPELESS:
            case DXGI_FORMAT_BC4_UNORM:
                ctx->tex_ratio = 8;
                ctx->tex_funct = ctx->texdsp.rgtc1u_block;
                break;
            case DXGI_FORMAT_BC4_SNORM:
                ctx->tex_ratio = 8;
                ctx->tex_funct = ctx->texdsp.rgtc1s_block;
                break;
            case DXGI_FORMAT_BC5_TYPELESS:
            case DXGI_FORMAT_BC5_UNORM:
                ctx->tex_ratio = 16;
                ctx->tex_funct = ctx->texdsp.rgtc2u_block;
                break;
            case DXGI_FORMAT_BC5_SNORM:
                ctx->tex_ratio = 16;
                ctx->tex_funct = ctx->texdsp.rgtc2s_block;
                break;
            default:
                av_log(avctx, AV_LOG_ERROR,
                       "Unsupported DXGI format %d.\n", dxgi);
                return AVERROR_INVALIDDATA;
            break;
        default:
            av_log(avctx, AV_LOG_ERROR, "Unsupported %s fourcc.\n", buf);
            return AVERROR_INVALIDDATA;
    } else if (ctx->paletted) {
        if (bpp == 8) {
            avctx->pix_fmt = AV_PIX_FMT_PAL8;
        } else {
            av_log(avctx, AV_LOG_ERROR, "Unsupported palette bpp %d.\n", bpp);
            return AVERROR_INVALIDDATA;
    } else {
        /*  8 bpp */
        if (bpp == 8 && r == 0xff && g == 0 && b == 0 && a == 0)
            avctx->pix_fmt = AV_PIX_FMT_GRAY8;
        /* 16 bpp */
        else if (bpp == 16 && r == 0xff && g == 0 && b == 0 && a == 0xff00)
            avctx->pix_fmt = AV_PIX_FMT_YA8;
        else if (bpp == 16 && r == 0xffff && g == 0 && b == 0 && a == 0)
            avctx->pix_fmt = AV_PIX_FMT_GRAY16LE;
        else if (bpp == 16 && r == 0xf800 && g == 0x7e0 && b == 0x1f && a == 0)
            avctx->pix_fmt = AV_PIX_FMT_RGB565LE;
        /* 24 bpp */
        else if (bpp == 24 && r == 0xff0000 && g == 0xff00 && b == 0xff && a == 0)
            avctx->pix_fmt = AV_PIX_FMT_BGR24;
        /* 32 bpp */
        else if (bpp == 32 && r == 0xff0000 && g == 0xff00 && b == 0xff && a == 0)
            avctx->pix_fmt = AV_PIX_FMT_BGRA; // opaque
        else if (bpp == 32 && r == 0xff && g == 0xff00 && b == 0xff0000 && a == 0)
            avctx->pix_fmt = AV_PIX_FMT_RGBA; // opaque
        else if (bpp == 32 && r == 0xff0000 && g == 0xff00 && b == 0xff && a == 0xff000000)
            avctx->pix_fmt = AV_PIX_FMT_BGRA;
        else if (bpp == 32 && r == 0xff && g == 0xff00 && b == 0xff0000 && a == 0xff000000)
            avctx->pix_fmt = AV_PIX_FMT_RGBA;
        /* give up */
        else {
            av_log(avctx, AV_LOG_ERROR, "Unknown pixel format "
                   "[bpp %d r 0x%x g 0x%x b 0x%x a 0x%x].\n", bpp, r, g, b, a);
            return AVERROR_INVALIDDATA;
    /* Set any remaining post-proc that should happen before frame is ready. */
    if (alpha_exponent)
        ctx->postproc = DDS_ALPHA_EXP;
    else if (normal_map)
        ctx->postproc = DDS_NORMAL_MAP;
    else if (ycocg_classic && !ctx->compressed)
        ctx->postproc = DDS_RAW_YCOCG;
    else if (avctx->pix_fmt == AV_PIX_FMT_YA8)
        ctx->postproc = DDS_SWAP_ALPHA;
    /* ATI/NVidia variants sometimes add swizzling in bpp. */
    switch (bpp) {
    case MKTAG('A', '2', 'X', 'Y'):
        ctx->postproc = DDS_SWIZZLE_A2XY;
        break;
    case MKTAG('x', 'G', 'B', 'R'):
        ctx->postproc = DDS_SWIZZLE_XGBR;
        break;
    case MKTAG('x', 'R', 'B', 'G'):
        ctx->postproc = DDS_SWIZZLE_XRBG;
        break;
    case MKTAG('R', 'B', 'x', 'G'):
        ctx->postproc = DDS_SWIZZLE_RBXG;
        break;
    case MKTAG('R', 'G', 'x', 'B'):
        ctx->postproc = DDS_SWIZZLE_RGXB;
        break;
    case MKTAG('R', 'x', 'B', 'G'):
        ctx->postproc = DDS_SWIZZLE_RXBG;
        break;
    case MKTAG('x', 'G', 'x', 'R'):
        ctx->postproc = DDS_SWIZZLE_XGXR;
        break;
    case MKTAG('A', '2', 'D', '5'):
        ctx->postproc = DDS_NORMAL_MAP;
        break;
    return 0;


static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)

{

    if (o->max*den < num*intnum || o->min*den > num*intnum) {

        av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range\n",

               num*intnum/den, o->name);

        return AVERROR(ERANGE);

    }

    switch (o->type) {

    case AV_OPT_TYPE_FLAGS:

    case AV_OPT_TYPE_INT:   *(int       *)dst= llrint(num/den)*intnum; break;

    case AV_OPT_TYPE_INT64: *(int64_t   *)dst= llrint(num/den)*intnum; break;

    case AV_OPT_TYPE_FLOAT: *(float     *)dst= num*intnum/den;         break;

    case AV_OPT_TYPE_DOUBLE:*(double    *)dst= num*intnum/den;         break;

    case AV_OPT_TYPE_RATIONAL:

        if ((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den};

        else                 *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);

        break;

    default:

        return AVERROR(EINVAL);

    }

    return 0;

}


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

{

    MIPSITUState *tag = (MIPSITUState *)opaque;

    uint64_t index = addr >> 3;

    uint64_t ret = 0;

    switch (index) {

    case 0 ... ITC_ADDRESSMAP_NUM:

        ret = tag->ITCAddressMap[index];

        break;

    default:

        qemu_log_mask(LOG_GUEST_ERROR, "Read 0x%" PRIx64 "\n", addr);

        break;

    }

    return ret;

}


static int calc_add_mv(RV34DecContext *r, int dir, int val)

{

    int mul = dir ? -r->mv_weight2 : r->mv_weight1;

    return (val * mul + 0x2000) >> 14;

}


static void put_line(uint8_t *dst, int size, int width, const int *runs)

{

    PutBitContext pb;

    int run, mode = ~0, pix_left = width, run_idx = 0;

    init_put_bits(&pb, dst, size * 8);

    while (pix_left > 0) {

        run       = runs[run_idx++];

        mode      = ~mode;

        pix_left -= run;

        for (; run > 16; run -= 16)

            put_sbits(&pb, 16, mode);

        if (run)

            put_sbits(&pb, run, mode);

    }

    flush_put_bits(&pb);

}


int ff_load_image(uint8_t *data[4], int linesize[4],

                  int *w, int *h, enum PixelFormat *pix_fmt,

                  const char *filename, void *log_ctx)

{

    AVInputFormat *iformat = NULL;

    AVFormatContext *format_ctx;

    AVCodec *codec;

    AVCodecContext *codec_ctx;

    AVFrame *frame;

    int frame_decoded, ret = 0;

    AVPacket pkt;

    av_register_all();

    iformat = av_find_input_format("image2");

    if ((ret = avformat_open_input(&format_ctx, filename, iformat, NULL)) < 0) {

        av_log(log_ctx, AV_LOG_ERROR,

               "Failed to open input file '%s'\n", filename);

        return ret;

    }

    codec_ctx = format_ctx->streams[0]->codec;

    codec = avcodec_find_decoder(codec_ctx->codec_id);

    if (!codec) {

        av_log(log_ctx, AV_LOG_ERROR, "Failed to find codec\n");

        ret = AVERROR(EINVAL);

        goto end;

    }

    if ((ret = avcodec_open2(codec_ctx, codec, NULL)) < 0) {

        av_log(log_ctx, AV_LOG_ERROR, "Failed to open codec\n");

        goto end;

    }

    if (!(frame = avcodec_alloc_frame()) ) {

        av_log(log_ctx, AV_LOG_ERROR, "Failed to alloc frame\n");

        ret = AVERROR(ENOMEM);

        goto end;

    }

    ret = av_read_frame(format_ctx, &pkt);

    if (ret < 0) {

        av_log(log_ctx, AV_LOG_ERROR, "Failed to read frame from file\n");

        goto end;

    }

    ret = avcodec_decode_video2(codec_ctx, frame, &frame_decoded, &pkt);

    if (ret < 0 || !frame_decoded) {

        av_log(log_ctx, AV_LOG_ERROR, "Failed to decode image from file\n");

        goto end;

    }

    ret = 0;

    *w       = frame->width;

    *h       = frame->height;

    *pix_fmt = frame->format;

    if ((ret = av_image_alloc(data, linesize, *w, *h, *pix_fmt, 16)) < 0)

        goto end;

    ret = 0;

    av_image_copy(data, linesize, frame->data, frame->linesize, *pix_fmt, *w, *h);

end:

    if (codec_ctx)

        avcodec_close(codec_ctx);

    if (format_ctx)

        avformat_close_input(&format_ctx);

    av_freep(&frame);

    if (ret < 0)

        av_log(log_ctx, AV_LOG_ERROR, "Error loading image file '%s'\n", filename);

    return ret;

}


void ff_vdpau_h264_picture_complete(MpegEncContext *s)

{

    H264Context *h = s->avctx->priv_data;

    struct vdpau_render_state *render;

    int i;

    render = (struct vdpau_render_state *)s->current_picture_ptr->data[0];

    assert(render);

    render->info.h264.slice_count = h->slice_num;

    if (render->info.h264.slice_count < 1)

        return;

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

        int foc = s->current_picture_ptr->field_poc[i];

        if (foc == INT_MAX)

            foc = 0;

        render->info.h264.field_order_cnt[i] = foc;

    }

    render->info.h264.is_reference                           = (s->current_picture_ptr->reference & 3) ? VDP_TRUE : VDP_FALSE;

    render->info.h264.frame_num                              = h->frame_num;

    render->info.h264.field_pic_flag                         = s->picture_structure != PICT_FRAME;

    render->info.h264.bottom_field_flag                      = s->picture_structure == PICT_BOTTOM_FIELD;

    render->info.h264.num_ref_frames                         = h->sps.ref_frame_count;

    render->info.h264.mb_adaptive_frame_field_flag           = h->sps.mb_aff && !render->info.h264.field_pic_flag;

    render->info.h264.constrained_intra_pred_flag            = h->pps.constrained_intra_pred;

    render->info.h264.weighted_pred_flag                     = h->pps.weighted_pred;

    render->info.h264.weighted_bipred_idc                    = h->pps.weighted_bipred_idc;

    render->info.h264.frame_mbs_only_flag                    = h->sps.frame_mbs_only_flag;

    render->info.h264.transform_8x8_mode_flag                = h->pps.transform_8x8_mode;

    render->info.h264.chroma_qp_index_offset                 = h->pps.chroma_qp_index_offset[0];

    render->info.h264.second_chroma_qp_index_offset          = h->pps.chroma_qp_index_offset[1];

    render->info.h264.pic_init_qp_minus26                    = h->pps.init_qp - 26;

    render->info.h264.num_ref_idx_l0_active_minus1           = h->pps.ref_count[0] - 1;

    render->info.h264.num_ref_idx_l1_active_minus1           = h->pps.ref_count[1] - 1;

    render->info.h264.log2_max_frame_num_minus4              = h->sps.log2_max_frame_num - 4;

    render->info.h264.pic_order_cnt_type                     = h->sps.poc_type;

    render->info.h264.log2_max_pic_order_cnt_lsb_minus4      = h->sps.log2_max_poc_lsb - 4;

    render->info.h264.delta_pic_order_always_zero_flag       = h->sps.delta_pic_order_always_zero_flag;

    render->info.h264.direct_8x8_inference_flag              = h->sps.direct_8x8_inference_flag;

    render->info.h264.entropy_coding_mode_flag               = h->pps.cabac;

    render->info.h264.pic_order_present_flag                 = h->pps.pic_order_present;

    render->info.h264.deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present;

    render->info.h264.redundant_pic_cnt_present_flag         = h->pps.redundant_pic_cnt_present;

    memcpy(render->info.h264.scaling_lists_4x4, h->pps.scaling_matrix4, sizeof(render->info.h264.scaling_lists_4x4));

    memcpy(render->info.h264.scaling_lists_8x8, h->pps.scaling_matrix8, sizeof(render->info.h264.scaling_lists_8x8));

    ff_draw_horiz_band(s, 0, s->avctx->height);

    render->bitstream_buffers_used = 0;

}


static void flat_print_int(WriterContext *wctx, const char *key, long long int value)

{

    flat_print_key_prefix(wctx);

    printf("%s=%lld\n", key, value);

}


void av_fifo_write(AVFifoBuffer *f, const uint8_t *buf, int size)

{

    while (size > 0) {

        int len = FFMIN(f->end - f->wptr, size);

        memcpy(f->wptr, buf, len);

        f->wptr += len;

        if (f->wptr >= f->end)

            f->wptr = f->buffer;

        buf += len;

        size -= len;

    }

}


static int handle_packets(MpegTSContext *ts, int nb_packets)

{

    AVFormatContext *s = ts->stream;

    uint8_t packet[TS_PACKET_SIZE];

    int packet_num, ret = 0;

    if (avio_tell(s->pb) != ts->last_pos) {

        int i;

        av_dlog("Skipping after seek\n");

        /* seek detected, flush pes buffer */

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

            if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) {

                PESContext *pes = ts->pids[i]->u.pes_filter.opaque;

                av_freep(&pes->buffer);

                ts->pids[i]->last_cc = -1;

                pes->data_index = 0;

                pes->state = MPEGTS_SKIP; /* skip until pes header */

            }

        }

    }

    ts->stop_parse = 0;

    packet_num = 0;

    for(;;) {

        if (ts->stop_parse>0)

            break;

        packet_num++;

        if (nb_packets != 0 && packet_num >= nb_packets)

            break;

        ret = read_packet(s, packet, ts->raw_packet_size);

        if (ret != 0)

            break;

        ret = handle_packet(ts, packet);

        if (ret != 0)

            break;

    }

    ts->last_pos = avio_tell(s->pb);

    return ret;

}