static void usb_serial_handle_data(USBDevice *dev, USBPacket *p)

{

    USBSerialState *s = (USBSerialState *)dev;

    uint8_t devep = p->ep->nr;

    struct iovec *iov;

    uint8_t header[2];

    int i, first_len, len;

    switch (p->pid) {

    case USB_TOKEN_OUT:

        if (devep != 2)

            goto fail;

        for (i = 0; i < p->iov.niov; i++) {

            iov = p->iov.iov + i;

            qemu_chr_fe_write(s->cs, iov->iov_base, iov->iov_len);

        }

        p->actual_length = p->iov.size;

        break;

    case USB_TOKEN_IN:

        if (devep != 1)

            goto fail;

        first_len = RECV_BUF - s->recv_ptr;

        len = p->iov.size;

        if (len <= 2) {

            p->status = USB_RET_NAK;

            break;

        }

        header[0] = usb_get_modem_lines(s) | 1;

        /* We do not have the uart details */

        /* handle serial break */

        if (s->event_trigger && s->event_trigger & FTDI_BI) {

            s->event_trigger &= ~FTDI_BI;

            header[1] = FTDI_BI;

            usb_packet_copy(p, header, 2);

            break;

        } else {

            header[1] = 0;

        }

        len -= 2;

        if (len > s->recv_used)

            len = s->recv_used;

        if (!len) {

            p->status = USB_RET_NAK;

            break;

        }

        if (first_len > len)

            first_len = len;

        usb_packet_copy(p, header, 2);

        usb_packet_copy(p, s->recv_buf + s->recv_ptr, first_len);

        if (len > first_len)

            usb_packet_copy(p, s->recv_buf, len - first_len);

        s->recv_used -= len;

        s->recv_ptr = (s->recv_ptr + len) % RECV_BUF;

        break;

    default:

        DPRINTF("Bad token\n");

    fail:

        p->status = USB_RET_STALL;

        break;

    }

}


int ff_hevc_decode_nal_pps(HEVCContext *s)

{

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

    HEVCSPS      *sps = NULL;

    int pic_area_in_ctbs, pic_area_in_min_cbs, pic_area_in_min_tbs;

    int log2_diff_ctb_min_tb_size;

    int i, j, x, y, ctb_addr_rs, tile_id;

    int ret    = 0;

    int pps_id = 0;

    AVBufferRef *pps_buf;

    HEVCPPS *pps = av_mallocz(sizeof(*pps));

    if (!pps)

        return AVERROR(ENOMEM);

    pps_buf = av_buffer_create((uint8_t *)pps, sizeof(*pps),

                               hevc_pps_free, NULL, 0);

    if (!pps_buf) {

        av_freep(&pps);

        return AVERROR(ENOMEM);

    }

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

    // Default values

    pps->loop_filter_across_tiles_enabled_flag = 1;

    pps->num_tile_columns                      = 1;

    pps->num_tile_rows                         = 1;

    pps->uniform_spacing_flag                  = 1;

    pps->disable_dbf                           = 0;

    pps->beta_offset                           = 0;

    pps->tc_offset                             = 0;

    // Coded parameters

    pps_id = get_ue_golomb_long(gb);

    if (pps_id >= MAX_PPS_COUNT) {

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

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    pps->sps_id = get_ue_golomb_long(gb);

    if (pps->sps_id >= MAX_SPS_COUNT) {

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

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    if (!s->sps_list[pps->sps_id]) {

        av_log(s->avctx, AV_LOG_ERROR, "SPS %u does not exist.\n", pps->sps_id);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

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

    pps->dependent_slice_segments_enabled_flag = get_bits1(gb);

    pps->output_flag_present_flag              = get_bits1(gb);

    pps->num_extra_slice_header_bits           = get_bits(gb, 3);

    pps->sign_data_hiding_flag = get_bits1(gb);

    pps->cabac_init_present_flag = get_bits1(gb);

    pps->num_ref_idx_l0_default_active = get_ue_golomb_long(gb) + 1;

    pps->num_ref_idx_l1_default_active = get_ue_golomb_long(gb) + 1;

    pps->pic_init_qp_minus26 = get_se_golomb(gb);

    pps->constrained_intra_pred_flag = get_bits1(gb);

    pps->transform_skip_enabled_flag = get_bits1(gb);

    pps->cu_qp_delta_enabled_flag = get_bits1(gb);

    pps->diff_cu_qp_delta_depth   = 0;

    if (pps->cu_qp_delta_enabled_flag)

        pps->diff_cu_qp_delta_depth = get_ue_golomb_long(gb);

    pps->cb_qp_offset = get_se_golomb(gb);

    if (pps->cb_qp_offset < -12 || pps->cb_qp_offset > 12) {

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

               pps->cb_qp_offset);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    pps->cr_qp_offset = get_se_golomb(gb);

    if (pps->cr_qp_offset < -12 || pps->cr_qp_offset > 12) {

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

               pps->cr_qp_offset);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    pps->pic_slice_level_chroma_qp_offsets_present_flag = get_bits1(gb);

    pps->weighted_pred_flag   = get_bits1(gb);

    pps->weighted_bipred_flag = get_bits1(gb);

    pps->transquant_bypass_enable_flag    = get_bits1(gb);

    pps->tiles_enabled_flag               = get_bits1(gb);

    pps->entropy_coding_sync_enabled_flag = get_bits1(gb);

    if (pps->tiles_enabled_flag) {

        pps->num_tile_columns = get_ue_golomb_long(gb) + 1;

        pps->num_tile_rows    = get_ue_golomb_long(gb) + 1;

        if (pps->num_tile_columns == 0 ||

            pps->num_tile_columns >= sps->width) {

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

                   pps->num_tile_columns - 1);

            ret = AVERROR_INVALIDDATA;

            goto err;

        }

        if (pps->num_tile_rows == 0 ||

            pps->num_tile_rows >= sps->height) {

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

                   pps->num_tile_rows - 1);

            ret = AVERROR_INVALIDDATA;

            goto err;

        }

        pps->column_width = av_malloc_array(pps->num_tile_columns, sizeof(*pps->column_width));

        pps->row_height   = av_malloc_array(pps->num_tile_rows,    sizeof(*pps->row_height));

        if (!pps->column_width || !pps->row_height) {

            ret = AVERROR(ENOMEM);

            goto err;

        }

        pps->uniform_spacing_flag = get_bits1(gb);

        if (!pps->uniform_spacing_flag) {

            uint64_t sum = 0;

            for (i = 0; i < pps->num_tile_columns - 1; i++) {

                pps->column_width[i] = get_ue_golomb_long(gb) + 1;

                sum                 += pps->column_width[i];

            }

            if (sum >= sps->ctb_width) {

                av_log(s->avctx, AV_LOG_ERROR, "Invalid tile widths.\n");

                ret = AVERROR_INVALIDDATA;

                goto err;

            }

            pps->column_width[pps->num_tile_columns - 1] = sps->ctb_width - sum;

            sum = 0;

            for (i = 0; i < pps->num_tile_rows - 1; i++) {

                pps->row_height[i] = get_ue_golomb_long(gb) + 1;

                sum               += pps->row_height[i];

            }

            if (sum >= sps->ctb_height) {

                av_log(s->avctx, AV_LOG_ERROR, "Invalid tile heights.\n");

                ret = AVERROR_INVALIDDATA;

                goto err;

            }

            pps->row_height[pps->num_tile_rows - 1] = sps->ctb_height - sum;

        }

        pps->loop_filter_across_tiles_enabled_flag = get_bits1(gb);

    }

    pps->seq_loop_filter_across_slices_enabled_flag = get_bits1(gb);

    pps->deblocking_filter_control_present_flag = get_bits1(gb);

    if (pps->deblocking_filter_control_present_flag) {

        pps->deblocking_filter_override_enabled_flag = get_bits1(gb);

        pps->disable_dbf                             = get_bits1(gb);

        if (!pps->disable_dbf) {

            pps->beta_offset = get_se_golomb(gb) * 2;

            pps->tc_offset = get_se_golomb(gb) * 2;

            if (pps->beta_offset/2 < -6 || pps->beta_offset/2 > 6) {

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

                       pps->beta_offset/2);

                ret = AVERROR_INVALIDDATA;

                goto err;

            }

            if (pps->tc_offset/2 < -6 || pps->tc_offset/2 > 6) {

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

                       pps->tc_offset/2);

                ret = AVERROR_INVALIDDATA;

                goto err;

            }

        }

    }

    pps->scaling_list_data_present_flag = get_bits1(gb);

    if (pps->scaling_list_data_present_flag) {

        set_default_scaling_list_data(&pps->scaling_list);

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

        if (ret < 0)

            goto err;

    }

    pps->lists_modification_present_flag = get_bits1(gb);

    pps->log2_parallel_merge_level       = get_ue_golomb_long(gb) + 2;

    if (pps->log2_parallel_merge_level > sps->log2_ctb_size) {

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

               pps->log2_parallel_merge_level - 2);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    pps->slice_header_extension_present_flag = get_bits1(gb);

    skip_bits1(gb);     // pps_extension_flag

    // Inferred parameters

    pps->col_bd   = av_malloc_array(pps->num_tile_columns + 1, sizeof(*pps->col_bd));

    pps->row_bd   = av_malloc_array(pps->num_tile_rows + 1,    sizeof(*pps->row_bd));

    pps->col_idxX = av_malloc_array(sps->ctb_width,    sizeof(*pps->col_idxX));

    if (!pps->col_bd || !pps->row_bd || !pps->col_idxX) {

        ret = AVERROR(ENOMEM);

        goto err;

    }

    if (pps->uniform_spacing_flag) {

        if (!pps->column_width) {

            pps->column_width = av_malloc_array(pps->num_tile_columns, sizeof(*pps->column_width));

            pps->row_height   = av_malloc_array(pps->num_tile_rows,    sizeof(*pps->row_height));

        }

        if (!pps->column_width || !pps->row_height) {

            ret = AVERROR(ENOMEM);

            goto err;

        }

        for (i = 0; i < pps->num_tile_columns; i++) {

            pps->column_width[i] = ((i + 1) * sps->ctb_width) / pps->num_tile_columns -

                                   (i * sps->ctb_width) / pps->num_tile_columns;

        }

        for (i = 0; i < pps->num_tile_rows; i++) {

            pps->row_height[i] = ((i + 1) * sps->ctb_height) / pps->num_tile_rows -

                                 (i * sps->ctb_height) / pps->num_tile_rows;

        }

    }

    pps->col_bd[0] = 0;

    for (i = 0; i < pps->num_tile_columns; i++)

        pps->col_bd[i + 1] = pps->col_bd[i] + pps->column_width[i];

    pps->row_bd[0] = 0;

    for (i = 0; i < pps->num_tile_rows; i++)

        pps->row_bd[i + 1] = pps->row_bd[i] + pps->row_height[i];

    for (i = 0, j = 0; i < sps->ctb_width; i++) {

        if (i > pps->col_bd[j])

            j++;

        pps->col_idxX[i] = j;

    }

    /**

     * 6.5

     */

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

    pic_area_in_min_cbs  = sps->min_cb_width * sps->min_cb_height;

    pic_area_in_min_tbs  = sps->min_tb_width * sps->min_tb_height;

    pps->ctb_addr_rs_to_ts = av_malloc_array(pic_area_in_ctbs,    sizeof(*pps->ctb_addr_rs_to_ts));

    pps->ctb_addr_ts_to_rs = av_malloc_array(pic_area_in_ctbs,    sizeof(*pps->ctb_addr_ts_to_rs));

    pps->tile_id           = av_malloc_array(pic_area_in_ctbs,    sizeof(*pps->tile_id));

    pps->min_cb_addr_zs    = av_malloc_array(pic_area_in_min_cbs, sizeof(*pps->min_cb_addr_zs));

    pps->min_tb_addr_zs    = av_malloc_array(pic_area_in_min_tbs, sizeof(*pps->min_tb_addr_zs));

    if (!pps->ctb_addr_rs_to_ts || !pps->ctb_addr_ts_to_rs ||

        !pps->tile_id || !pps->min_cb_addr_zs || !pps->min_tb_addr_zs) {

        ret = AVERROR(ENOMEM);

        goto err;

    }

    for (ctb_addr_rs = 0; ctb_addr_rs < pic_area_in_ctbs; ctb_addr_rs++) {

        int tb_x   = ctb_addr_rs % sps->ctb_width;

        int tb_y   = ctb_addr_rs / sps->ctb_width;

        int tile_x = 0;

        int tile_y = 0;

        int val    = 0;

        for (i = 0; i < pps->num_tile_columns; i++) {

            if (tb_x < pps->col_bd[i + 1]) {

                tile_x = i;

                break;

            }

        }

        for (i = 0; i < pps->num_tile_rows; i++) {

            if (tb_y < pps->row_bd[i + 1]) {

                tile_y = i;

                break;

            }

        }

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

            val += pps->row_height[tile_y] * pps->column_width[i];

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

            val += sps->ctb_width * pps->row_height[i];

        val += (tb_y - pps->row_bd[tile_y]) * pps->column_width[tile_x] +

               tb_x - pps->col_bd[tile_x];

        pps->ctb_addr_rs_to_ts[ctb_addr_rs] = val;

        pps->ctb_addr_ts_to_rs[val]         = ctb_addr_rs;

    }

    for (j = 0, tile_id = 0; j < pps->num_tile_rows; j++)

        for (i = 0; i < pps->num_tile_columns; i++, tile_id++)

            for (y = pps->row_bd[j]; y < pps->row_bd[j + 1]; y++)

                for (x = pps->col_bd[i]; x < pps->col_bd[i + 1]; x++)

                    pps->tile_id[pps->ctb_addr_rs_to_ts[y * sps->ctb_width + x]] = tile_id;

    pps->tile_pos_rs = av_malloc_array(tile_id, sizeof(*pps->tile_pos_rs));

    if (!pps->tile_pos_rs) {

        ret = AVERROR(ENOMEM);

        goto err;

    }

    for (j = 0; j < pps->num_tile_rows; j++)

        for (i = 0; i < pps->num_tile_columns; i++)

            pps->tile_pos_rs[j * pps->num_tile_columns + i] = pps->row_bd[j] * sps->ctb_width + pps->col_bd[i];

    for (y = 0; y < sps->min_cb_height; y++) {

        for (x = 0; x < sps->min_cb_width; x++) {

            int tb_x        = x >> sps->log2_diff_max_min_coding_block_size;

            int tb_y        = y >> sps->log2_diff_max_min_coding_block_size;

            int ctb_addr_rs = sps->ctb_width * tb_y + tb_x;

            int val         = pps->ctb_addr_rs_to_ts[ctb_addr_rs] <<

                              (sps->log2_diff_max_min_coding_block_size * 2);

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

                int m = 1 << i;

                val += (m & x ? m * m : 0) + (m & y ? 2 * m * m : 0);

            }

            pps->min_cb_addr_zs[y * sps->min_cb_width + x] = val;

        }

    }

    log2_diff_ctb_min_tb_size = sps->log2_ctb_size - sps->log2_min_tb_size;

    for (y = 0; y < sps->min_tb_height; y++) {

        for (x = 0; x < sps->min_tb_width; x++) {

            int tb_x        = x >> log2_diff_ctb_min_tb_size;

            int tb_y        = y >> log2_diff_ctb_min_tb_size;

            int ctb_addr_rs = sps->ctb_width * tb_y + tb_x;

            int val         = pps->ctb_addr_rs_to_ts[ctb_addr_rs] <<

                              (log2_diff_ctb_min_tb_size * 2);

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

                int m = 1 << i;

                val += (m & x ? m * m : 0) + (m & y ? 2 * m * m : 0);

            }

            pps->min_tb_addr_zs[y * sps->min_tb_width + x] = val;

        }

    }

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

    s->pps_list[pps_id] = pps_buf;

    return 0;

err:

    av_buffer_unref(&pps_buf);

    return ret;

}


static int raw_read_options(QDict *options, BlockDriverState *bs,

    BDRVRawState *s, Error **errp)

{

    Error *local_err = NULL;

    QemuOpts *opts = NULL;

    int64_t real_size = 0;

    int ret;

    real_size = bdrv_getlength(bs->file->bs);

    if (real_size < 0) {

        error_setg_errno(errp, -real_size, "Could not get image size");

        return real_size;

    }

    opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort);

    qemu_opts_absorb_qdict(opts, options, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        ret = -EINVAL;

        goto end;

    }

    s->offset = qemu_opt_get_size(opts, "offset", 0);

    if (s->offset > real_size) {

        error_setg(errp, "Offset (%" PRIu64 ") cannot be greater than "

            "size of the containing file (%" PRId64 ")",

            s->offset, real_size);

        ret = -EINVAL;

        goto end;

    }

    if (qemu_opt_find(opts, "size") != NULL) {

        s->size = qemu_opt_get_size(opts, "size", 0);

        s->has_size = true;

    } else {

        s->has_size = false;

        s->size = real_size - s->offset;

    }

    /* Check size and offset */

    if ((real_size - s->offset) < s->size) {

        error_setg(errp, "The sum of offset (%" PRIu64 ") and size "

            "(%" PRIu64 ") has to be smaller or equal to the "

            " actual size of the containing file (%" PRId64 ")",

            s->offset, s->size, real_size);

        ret = -EINVAL;

        goto end;

    }

    /* Make sure size is multiple of BDRV_SECTOR_SIZE to prevent rounding

     * up and leaking out of the specified area. */

    if (!QEMU_IS_ALIGNED(s->size, BDRV_SECTOR_SIZE)) {

        error_setg(errp, "Specified size is not multiple of %llu",

            BDRV_SECTOR_SIZE);

        ret = -EINVAL;

        goto end;

    }

    ret = 0;

end:

    qemu_opts_del(opts);

    return ret;

}


inline static void RENAME(hcscale)(uint16_t *dst, long dstWidth, uint8_t *src1, uint8_t *src2,

                                   int srcW, int xInc, int flags, int canMMX2BeUsed, int16_t *hChrFilter,

                                   int16_t *hChrFilterPos, int hChrFilterSize, void *funnyUVCode,

                                   int srcFormat, uint8_t *formatConvBuffer, int16_t *mmx2Filter,

                                   int32_t *mmx2FilterPos, uint8_t *pal)

{

    if (srcFormat==PIX_FMT_YUYV422)

    {

        RENAME(yuy2ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

        src1= formatConvBuffer;

        src2= formatConvBuffer+2048;

    }

    else if (srcFormat==PIX_FMT_UYVY422)

    {

        RENAME(uyvyToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

        src1= formatConvBuffer;

        src2= formatConvBuffer+2048;

    }

    else if (srcFormat==PIX_FMT_RGB32)

    {

        RENAME(bgr32ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

        src1= formatConvBuffer;

        src2= formatConvBuffer+2048;

    }

    else if (srcFormat==PIX_FMT_BGR24)

    {

        RENAME(bgr24ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

        src1= formatConvBuffer;

        src2= formatConvBuffer+2048;

    }

    else if (srcFormat==PIX_FMT_BGR565)

    {

        RENAME(bgr16ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

        src1= formatConvBuffer;

        src2= formatConvBuffer+2048;

    }

    else if (srcFormat==PIX_FMT_BGR555)

    {

        RENAME(bgr15ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

        src1= formatConvBuffer;

        src2= formatConvBuffer+2048;

    }

    else if (srcFormat==PIX_FMT_BGR32)

    {

        RENAME(rgb32ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

        src1= formatConvBuffer;

        src2= formatConvBuffer+2048;

    }

    else if (srcFormat==PIX_FMT_RGB24)

    {

        RENAME(rgb24ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

        src1= formatConvBuffer;

        src2= formatConvBuffer+2048;

    }

    else if (srcFormat==PIX_FMT_RGB565)

    {

        RENAME(rgb16ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

        src1= formatConvBuffer;

        src2= formatConvBuffer+2048;

    }

    else if (srcFormat==PIX_FMT_RGB555)

    {

        RENAME(rgb15ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

        src1= formatConvBuffer;

        src2= formatConvBuffer+2048;

    }

    else if (isGray(srcFormat))

    {

        return;

    }

    else if (srcFormat==PIX_FMT_RGB8 || srcFormat==PIX_FMT_BGR8 || srcFormat==PIX_FMT_PAL8 || srcFormat==PIX_FMT_BGR4_BYTE  || srcFormat==PIX_FMT_RGB4_BYTE)

    {

        RENAME(palToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW, pal);

        src1= formatConvBuffer;

        src2= formatConvBuffer+2048;

    }

#ifdef HAVE_MMX

    // use the new MMX scaler if the mmx2 can't be used (it is faster than the x86 ASM one)

    if (!(flags&SWS_FAST_BILINEAR) || (!canMMX2BeUsed))

#else

    if (!(flags&SWS_FAST_BILINEAR))

#endif

    {

        RENAME(hScale)(dst     , dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);

        RENAME(hScale)(dst+2048, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);

    }

    else // Fast Bilinear upscale / crap downscale

    {

#if defined(ARCH_X86)

#ifdef HAVE_MMX2

        int i;

#if defined(PIC)

        uint64_t ebxsave __attribute__((aligned(8)));

#endif

        if (canMMX2BeUsed)

        {

            asm volatile(

#if defined(PIC)

            "mov          %%"REG_b", %6         \n\t"

#endif

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

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

            "mov                 %1, %%"REG_D"  \n\t"

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

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

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

            PREFETCH"   (%%"REG_c")             \n\t"

            PREFETCH" 32(%%"REG_c")             \n\t"

            PREFETCH" 64(%%"REG_c")             \n\t"

#ifdef ARCH_X86_64

#define FUNNY_UV_CODE \

            "movl       (%%"REG_b"), %%esi      \n\t"\

            "call               *%4             \n\t"\

            "movl (%%"REG_b", %%"REG_a"), %%esi \n\t"\

            "add          %%"REG_S", %%"REG_c"  \n\t"\

            "add          %%"REG_a", %%"REG_D"  \n\t"\

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

#else

#define FUNNY_UV_CODE \

            "movl       (%%"REG_b"), %%esi      \n\t"\

            "call               *%4             \n\t"\

            "addl (%%"REG_b", %%"REG_a"), %%"REG_c" \n\t"\

            "add          %%"REG_a", %%"REG_D"  \n\t"\

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

#endif /* ARCH_X86_64 */

FUNNY_UV_CODE

FUNNY_UV_CODE

FUNNY_UV_CODE

FUNNY_UV_CODE

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

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

            "mov                 %1, %%"REG_D"  \n\t" // buf1

            "add              $4096, %%"REG_D"  \n\t"

            PREFETCH"   (%%"REG_c")             \n\t"

            PREFETCH" 32(%%"REG_c")             \n\t"

            PREFETCH" 64(%%"REG_c")             \n\t"

FUNNY_UV_CODE

FUNNY_UV_CODE

FUNNY_UV_CODE

FUNNY_UV_CODE

#if defined(PIC)

            "mov %6, %%"REG_b"    \n\t"

#endif

            :: "m" (src1), "m" (dst), "m" (mmx2Filter), "m" (mmx2FilterPos),

            "m" (funnyUVCode), "m" (src2)

#if defined(PIC)

            ,"m" (ebxsave)

#endif

            : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D

#if !defined(PIC)

             ,"%"REG_b

#endif

            );

            for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--)

            {

                //printf("%d %d %d\n", dstWidth, i, srcW);

                dst[i] = src1[srcW-1]*128;

                dst[i+2048] = src2[srcW-1]*128;

            }

        }

        else

        {

#endif /* HAVE_MMX2 */

            long xInc_shr16 = (long) (xInc >> 16);

            uint16_t xInc_mask = xInc & 0xffff;

            asm volatile(

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

            "xor %%"REG_d", %%"REG_d"               \n\t" // xx

            "xorl    %%ecx, %%ecx                   \n\t" // 2*xalpha

            ASMALIGN(4)

            "1:                                     \n\t"

            "mov        %0, %%"REG_S"               \n\t"

            "movzbl  (%%"REG_S", %%"REG_d"), %%edi  \n\t" //src[xx]

            "movzbl 1(%%"REG_S", %%"REG_d"), %%esi  \n\t" //src[xx+1]

            "subl    %%edi, %%esi                   \n\t" //src[xx+1] - src[xx]

            "imull   %%ecx, %%esi                   \n\t" //(src[xx+1] - src[xx])*2*xalpha

            "shll      $16, %%edi                   \n\t"

            "addl    %%edi, %%esi                   \n\t" //src[xx+1]*2*xalpha + src[xx]*(1-2*xalpha)

            "mov        %1, %%"REG_D"               \n\t"

            "shrl       $9, %%esi                   \n\t"

            "movw     %%si, (%%"REG_D", %%"REG_a", 2)   \n\t"

            "movzbl    (%5, %%"REG_d"), %%edi       \n\t" //src[xx]

            "movzbl   1(%5, %%"REG_d"), %%esi       \n\t" //src[xx+1]

            "subl    %%edi, %%esi                   \n\t" //src[xx+1] - src[xx]

            "imull   %%ecx, %%esi                   \n\t" //(src[xx+1] - src[xx])*2*xalpha

            "shll      $16, %%edi                   \n\t"

            "addl    %%edi, %%esi                   \n\t" //src[xx+1]*2*xalpha + src[xx]*(1-2*xalpha)

            "mov        %1, %%"REG_D"               \n\t"

            "shrl       $9, %%esi                   \n\t"

            "movw     %%si, 4096(%%"REG_D", %%"REG_a", 2)   \n\t"

            "addw       %4, %%cx                    \n\t" //2*xalpha += xInc&0xFF

            "adc        %3, %%"REG_d"               \n\t" //xx+= xInc>>8 + carry

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

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

            " jb        1b                          \n\t"

/* GCC-3.3 makes MPlayer crash on IA-32 machines when using "g" operand here,

   which is needed to support GCC-4.0 */

#if defined(ARCH_X86_64) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))

            :: "m" (src1), "m" (dst), "g" ((long)dstWidth), "m" (xInc_shr16), "m" (xInc_mask),

#else

            :: "m" (src1), "m" (dst), "m" ((long)dstWidth), "m" (xInc_shr16), "m" (xInc_mask),

#endif

            "r" (src2)

            : "%"REG_a, "%"REG_d, "%ecx", "%"REG_D, "%esi"

            );

#ifdef HAVE_MMX2

        } //if MMX2 can't be used

#endif

#else

        int i;

        unsigned int xpos=0;

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

        {

            register unsigned int xx=xpos>>16;

            register unsigned int xalpha=(xpos&0xFFFF)>>9;

            dst[i]=(src1[xx]*(xalpha^127)+src1[xx+1]*xalpha);

            dst[i+2048]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha);

            /* slower

            dst[i]= (src1[xx]<<7) + (src1[xx+1] - src1[xx])*xalpha;

            dst[i+2048]=(src2[xx]<<7) + (src2[xx+1] - src2[xx])*xalpha;

            */

            xpos+=xInc;

        }

#endif /* defined(ARCH_X86) */

    }

}


uint64_t cpu_tick_get_count(CPUTimer *timer)

{

    uint64_t real_count = timer_to_cpu_ticks(

                    qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->clock_offset,

                    timer->frequency);

    TIMER_DPRINTF("%s get_count count=0x%016lx (%s) p=%p\n",

           timer->name, real_count,

           timer->disabled?"disabled":"enabled", timer);

    if (timer->disabled)

        real_count |= timer->disabled_mask;

    return real_count;

}


static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)

{

    AVStream *st;

    char color_parameter_type[5] = { 0 };

    int color_primaries, color_trc, color_matrix;

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

        return 0;

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

    avio_read(pb, color_parameter_type, 4);

    if (strncmp(color_parameter_type, "nclx", 4) &&

        strncmp(color_parameter_type, "nclc", 4)) {

        av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",

               color_parameter_type);

        return 0;

    }

    color_primaries = avio_rb16(pb);

    color_trc = avio_rb16(pb);

    color_matrix = avio_rb16(pb);

    av_log(c->fc, AV_LOG_TRACE,

           "%s: pri %"PRIu16" trc %"PRIu16" matrix %"PRIu16"",

           color_parameter_type, color_primaries, color_trc, color_matrix);

    if (!strncmp(color_parameter_type, "nclx", 4)) {

        uint8_t color_range = avio_r8(pb) >> 7;

        av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);

        if (color_range)

            st->codec->color_range = AVCOL_RANGE_JPEG;

        else

            st->codec->color_range = AVCOL_RANGE_MPEG;

        /* 14496-12 references JPEG XR specs (rather than the more complete

         * 23001-8) so some adjusting is required */

        if (color_primaries >= AVCOL_PRI_FILM)

            color_primaries = AVCOL_PRI_UNSPECIFIED;

        if ((color_trc >= AVCOL_TRC_LINEAR &&

             color_trc <= AVCOL_TRC_LOG_SQRT) ||

            color_trc >= AVCOL_TRC_BT2020_10)

            color_trc = AVCOL_TRC_UNSPECIFIED;

        if (color_matrix >= AVCOL_SPC_BT2020_NCL)

            color_matrix = AVCOL_SPC_UNSPECIFIED;

        st->codec->color_primaries = color_primaries;

        st->codec->color_trc = color_trc;

        st->codec->colorspace = color_matrix;

    } else if (!strncmp(color_parameter_type, "nclc", 4)) {

        /* color primaries, Table 4-4 */

        switch (color_primaries) {

        case 1: st->codec->color_primaries = AVCOL_PRI_BT709; break;

        case 5: st->codec->color_primaries = AVCOL_PRI_SMPTE170M; break;

        case 6: st->codec->color_primaries = AVCOL_PRI_SMPTE240M; break;

        }

        /* color transfer, Table 4-5 */

        switch (color_trc) {

        case 1: st->codec->color_trc = AVCOL_TRC_BT709; break;

        case 7: st->codec->color_trc = AVCOL_TRC_SMPTE240M; break;

        }

        /* color matrix, Table 4-6 */

        switch (color_matrix) {

        case 1: st->codec->colorspace = AVCOL_SPC_BT709; break;

        case 6: st->codec->colorspace = AVCOL_SPC_BT470BG; break;

        case 7: st->codec->colorspace = AVCOL_SPC_SMPTE240M; break;

        }

    }

    av_log(c->fc, AV_LOG_TRACE, "\n");

    return 0;

}


void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)

{

    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);

    CPUState *cs = CPU(cpu);

    struct DisasContext ctx, *dc = &ctx;

    uint32_t pc_start;

    uint32_t next_page_start;

    int num_insns;

    int max_insns;

    pc_start = tb->pc;

    dc->tb = tb;

    dc->is_jmp = DISAS_NEXT;

    dc->ppc = pc_start;

    dc->pc = pc_start;

    dc->flags = cpu->env.cpucfgr;

    dc->mem_idx = cpu_mmu_index(&cpu->env, false);

    dc->synced_flags = dc->tb_flags = tb->flags;

    dc->delayed_branch = !!(dc->tb_flags & D_FLAG);

    dc->singlestep_enabled = cs->singlestep_enabled;

    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;

    num_insns = 0;

    max_insns = tb->cflags & CF_COUNT_MASK;

    if (max_insns == 0) {

        max_insns = CF_COUNT_MASK;

    }

    if (max_insns > TCG_MAX_INSNS) {

        max_insns = TCG_MAX_INSNS;

    }

    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)

        && qemu_log_in_addr_range(pc_start)) {

        qemu_log_lock();

        qemu_log("----------------\n");

        qemu_log("IN: %s\n", lookup_symbol(pc_start));

    }

    gen_tb_start(tb);

    do {

        tcg_gen_insn_start(dc->pc);

        num_insns++;

        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {

            tcg_gen_movi_tl(cpu_pc, dc->pc);

            gen_exception(dc, EXCP_DEBUG);

            dc->is_jmp = DISAS_UPDATE;

            /* The address covered by the breakpoint must be included in

               [tb->pc, tb->pc + tb->size) in order to for it to be

               properly cleared -- thus we increment the PC here so that

               the logic setting tb->size below does the right thing.  */

            dc->pc += 4;

            break;

        }

        if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {

            gen_io_start();

        }

        dc->ppc = dc->pc - 4;

        dc->npc = dc->pc + 4;

        tcg_gen_movi_tl(cpu_ppc, dc->ppc);

        tcg_gen_movi_tl(cpu_npc, dc->npc);

        disas_openrisc_insn(dc, cpu);

        dc->pc = dc->npc;

        /* delay slot */

        if (dc->delayed_branch) {

            dc->delayed_branch--;

            if (!dc->delayed_branch) {

                dc->tb_flags &= ~D_FLAG;

                gen_sync_flags(dc);

                tcg_gen_mov_tl(cpu_pc, jmp_pc);

                tcg_gen_mov_tl(cpu_npc, jmp_pc);

                tcg_gen_movi_tl(jmp_pc, 0);

                tcg_gen_exit_tb(0);

                dc->is_jmp = DISAS_JUMP;

                break;

            }

        }

    } while (!dc->is_jmp

             && !tcg_op_buf_full()

             && !cs->singlestep_enabled

             && !singlestep

             && (dc->pc < next_page_start)

             && num_insns < max_insns);

    if (tb->cflags & CF_LAST_IO) {

        gen_io_end();

    }

    if (dc->is_jmp == DISAS_NEXT) {

        dc->is_jmp = DISAS_UPDATE;

        tcg_gen_movi_tl(cpu_pc, dc->pc);

    }

    if (unlikely(cs->singlestep_enabled)) {

        if (dc->is_jmp == DISAS_NEXT) {

            tcg_gen_movi_tl(cpu_pc, dc->pc);

        }

        gen_exception(dc, EXCP_DEBUG);

    } else {

        switch (dc->is_jmp) {

        case DISAS_NEXT:

            gen_goto_tb(dc, 0, dc->pc);

            break;

        default:

        case DISAS_JUMP:

            break;

        case DISAS_UPDATE:

            /* indicate that the hash table must be used

               to find the next TB */

            tcg_gen_exit_tb(0);

            break;

        case DISAS_TB_JUMP:

            /* nothing more to generate */

            break;

        }

    }

    gen_tb_end(tb, num_insns);

    tb->size = dc->pc - pc_start;

    tb->icount = num_insns;

    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)

        && qemu_log_in_addr_range(pc_start)) {

        log_target_disas(cs, pc_start, tb->size, 0);

        qemu_log("\n");

        qemu_log_unlock();

    }

}


static int videotoolbox_common_end_frame(AVCodecContext *avctx, AVFrame *frame)

{

    int status;

    AVVideotoolboxContext *videotoolbox = avctx->hwaccel_context;

    VTContext *vtctx = avctx->internal->hwaccel_priv_data;

    av_buffer_unref(&frame->buf[0]);

    if (!videotoolbox->session || !vtctx->bitstream)

        return AVERROR_INVALIDDATA;

    status = videotoolbox_session_decode_frame(avctx);

    if (status) {

        av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);

        return AVERROR_UNKNOWN;

    }

    if (!vtctx->frame)

        return AVERROR_UNKNOWN;

    return ff_videotoolbox_buffer_create(vtctx, frame);

}


static void block_job_completed_single(BlockJob *job)

{

    if (!job->ret) {

        if (job->driver->commit) {

            job->driver->commit(job);

    } else {

        if (job->driver->abort) {

            job->driver->abort(job);

    if (job->cb) {

        job->cb(job->opaque, job->ret);

    if (block_job_is_cancelled(job)) {

        block_job_event_cancelled(job);

    } else {

        const char *msg = NULL;

        if (job->ret < 0) {

            msg = strerror(-job->ret);

        block_job_event_completed(job, msg);

    if (job->txn) {

        QLIST_REMOVE(job, txn_list);

        block_job_txn_unref(job->txn);

    block_job_unref(job);


static UHCIQueue *uhci_queue_get(UHCIState *s, UHCI_TD *td, USBEndpoint *ep)

{

    uint32_t token = uhci_queue_token(td);

    UHCIQueue *queue;

    QTAILQ_FOREACH(queue, &s->queues, next) {

        if (queue->token == token) {

            return queue;

        }

    }

    queue = g_new0(UHCIQueue, 1);

    queue->uhci = s;

    queue->token = token;

    queue->ep = ep;

    QTAILQ_INIT(&queue->asyncs);

    QTAILQ_INSERT_HEAD(&s->queues, queue, next);

    trace_usb_uhci_queue_add(queue->token);

    return queue;

}


HBitmap *hbitmap_alloc(uint64_t size, int granularity)

{

    HBitmap *hb = g_malloc0(sizeof (struct HBitmap));

    unsigned i;

    assert(granularity >= 0 && granularity < 64);

    size = (size + (1ULL << granularity) - 1) >> granularity;

    assert(size <= ((uint64_t)1 << HBITMAP_LOG_MAX_SIZE));

    hb->size = size;

    hb->granularity = granularity;

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

        size = MAX((size + BITS_PER_LONG - 1) >> BITS_PER_LEVEL, 1);

        hb->levels[i] = g_malloc0(size * sizeof(unsigned long));

    }

    /* We necessarily have free bits in level 0 due to the definition

     * of HBITMAP_LEVELS, so use one for a sentinel.  This speeds up

     * hbitmap_iter_skip_words.

     */

    assert(size == 1);

    hb->levels[0][0] |= 1UL << (BITS_PER_LONG - 1);

    return hb;

}


static int mp3_read_header(AVFormatContext *s)

{

    MP3DecContext *mp3 = s->priv_data;

    AVStream *st;

    int64_t off;

    int ret;

    int i;

    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

    st->codec->codec_id = AV_CODEC_ID_MP3;

    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;

    st->start_time = 0;

    // lcm of all mp3 sample rates

    avpriv_set_pts_info(st, 64, 1, 14112000);

    s->pb->maxsize = -1;

    off = avio_tell(s->pb);

    if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))

        ff_id3v1_read(s);

    if(s->pb->seekable)

        mp3->filesize = avio_size(s->pb);

    if (mp3_parse_vbr_tags(s, st, off) < 0)

        avio_seek(s->pb, off, SEEK_SET);

    ret = ff_replaygain_export(st, s->metadata);

    if (ret < 0)

        return ret;

    off = avio_tell(s->pb);

    for (i = 0; i < 64 * 1024; i++) {

        uint32_t header, header2;

        int frame_size;

        if (!(i&1023))

            ffio_ensure_seekback(s->pb, i + 1024 + 4);

        frame_size = check(s->pb, off + i, &header);

        if (frame_size > 0) {

            avio_seek(s->pb, off, SEEK_SET);

            ffio_ensure_seekback(s->pb, i + 1024 + frame_size + 4);

            if (check(s->pb, off + i + frame_size, &header2) >= 0 &&

                (header & SAME_HEADER_MASK) == (header2 & SAME_HEADER_MASK))

            {

                av_log(s, AV_LOG_INFO, "Skipping %d bytes of junk at %"PRId64".\n", i, off);

                avio_seek(s->pb, off + i, SEEK_SET);

                break;

            }

        }

        avio_seek(s->pb, off, SEEK_SET);

    }

    // the seek index is relative to the end of the xing vbr headers

    for (i = 0; i < st->nb_index_entries; i++)

        st->index_entries[i].pos += avio_tell(s->pb);

    /* the parameters will be extracted from the compressed bitstream */

    return 0;

}


static av_cold int close_decoder(AVCodecContext *avctx)

{

    PGSSubContext *ctx = avctx->priv_data;

    av_freep(&ctx->picture.rle);

    ctx->picture.rle_buffer_size  = 0;

    return 0;

}


static int gsm_parse(AVCodecParserContext *s1, AVCodecContext *avctx,

                     const uint8_t **poutbuf, int *poutbuf_size,

                     const uint8_t *buf, int buf_size)

{

    GSMParseContext *s = s1->priv_data;

    ParseContext *pc = &s->pc;

    int next;

    if (!s->block_size) {

        switch (avctx->codec_id) {

        case AV_CODEC_ID_GSM:

            s->block_size = GSM_BLOCK_SIZE;

            s->duration   = GSM_FRAME_SIZE;

            break;

        case AV_CODEC_ID_GSM_MS:

            s->block_size = GSM_MS_BLOCK_SIZE;

            s->duration   = GSM_FRAME_SIZE * 2;

            break;

        default:

            return AVERROR(EINVAL);

        }

    }

    if (!s->remaining)

        s->remaining = s->block_size;

    if (s->remaining <= buf_size) {

        next = s->remaining;

        s->remaining = 0;

    } else {

        next = END_NOT_FOUND;

        s->remaining -= buf_size;

    }

    if (ff_combine_frame(pc, next, &buf, &buf_size) < 0 || !buf_size) {

        *poutbuf      = NULL;

        *poutbuf_size = 0;

        return buf_size;

    }

    s1->duration = s->duration;

    *poutbuf      = buf;

    *poutbuf_size = buf_size;

    return next;

}


static void put_ebml_uint(ByteIOContext *pb, unsigned int elementid, uint64_t val)

{

    int i, bytes = 1;

    while (val >> bytes*8) bytes++;

    put_ebml_id(pb, elementid);

    put_ebml_num(pb, bytes, 0);

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

        put_byte(pb, val >> i*8);

}


static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)

{

    VideoState *is = opaque;

    int audio_size, len1;

    int bytes_per_sec;

    int frame_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, 1, is->audio_tgt.fmt, 1);

    double pts;

    audio_callback_time = av_gettime();

    while (len > 0) {

        if (is->audio_buf_index >= is->audio_buf_size) {

           audio_size = audio_decode_frame(is, &pts);

           if (audio_size < 0) {

                /* if error, just output silence */

               is->audio_buf      = is->silence_buf;

               is->audio_buf_size = sizeof(is->silence_buf) / frame_size * frame_size;

           } else {

               if (is->show_mode != SHOW_MODE_VIDEO)

                   update_sample_display(is, (int16_t *)is->audio_buf, audio_size);

               is->audio_buf_size = audio_size;

           }

           is->audio_buf_index = 0;

        }

        len1 = is->audio_buf_size - is->audio_buf_index;

        if (len1 > len)

            len1 = len;

        memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);

        len -= len1;

        stream += len1;

        is->audio_buf_index += len1;

    }

    bytes_per_sec = is->audio_tgt.freq * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);

    is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;

    /* Let's assume the audio driver that is used by SDL has two periods. */

    is->audio_current_pts = is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / bytes_per_sec;

    is->audio_current_pts_drift = is->audio_current_pts - audio_callback_time / 1000000.0;

    check_external_clock_sync(is, is->audio_current_pts);

}


static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)

{

    char desc[DESC_SIZE], tmp_desc[DESC_SIZE];

    char *p_name, *tmp_str;

    /* the descriptor offset = 0x200 */

    if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)

        return -1;

    tmp_str = strstr(desc,"parentCID");

    pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str);

    if ((p_name = strstr(desc,"CID")) != NULL) {

        p_name += sizeof("CID");

        snprintf(p_name, sizeof(desc) - (p_name - desc), "%x\n", cid);

        pstrcat(desc, sizeof(desc), tmp_desc);

    }

    if (bdrv_pwrite(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)

        return -1;

    return 0;

}


static int process_input(void)

{

    InputFile *ifile;

    AVFormatContext *is;

    InputStream *ist;

    AVPacket pkt;

    int ret, i, j;

    /* select the stream that we must read now */

    ifile = select_input_file();

    /* if none, if is finished */

    if (!ifile) {

        if (got_eagain()) {

            reset_eagain();

            av_usleep(10000);

            return AVERROR(EAGAIN);

        }

        av_log(NULL, AV_LOG_VERBOSE, "No more inputs to read from.\n");

        return AVERROR_EOF;

    }

    is  = ifile->ctx;

    ret = get_input_packet(ifile, &pkt);

    if (ret == AVERROR(EAGAIN)) {

        ifile->eagain = 1;

        return ret;

    }

    if (ret < 0) {

        if (ret != AVERROR_EOF) {

            print_error(is->filename, ret);

            if (exit_on_error)

                exit(1);

        }

        ifile->eof_reached = 1;

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

            ist = input_streams[ifile->ist_index + i];

            if (ist->decoding_needed)

                output_packet(ist, NULL);

            /* mark all outputs that don't go through lavfi as finished */

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

                OutputStream *ost = output_streams[j];

                if (ost->source_index == ifile->ist_index + i &&

                    (ost->stream_copy || ost->enc->type == AVMEDIA_TYPE_SUBTITLE))

                    ost->finished= 1;

            }

        }

        return AVERROR(EAGAIN);

    }

    reset_eagain();

    if (do_pkt_dump) {

        av_pkt_dump_log2(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump,

                         is->streams[pkt.stream_index]);

    }

    /* the following test is needed in case new streams appear

       dynamically in stream : we ignore them */

    if (pkt.stream_index >= ifile->nb_streams)

        goto discard_packet;

    ist = input_streams[ifile->ist_index + pkt.stream_index];

    if (ist->discard)

        goto discard_packet;

    if (pkt.dts != AV_NOPTS_VALUE)

        pkt.dts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base);

    if (pkt.pts != AV_NOPTS_VALUE)

        pkt.pts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base);

    if (pkt.pts != AV_NOPTS_VALUE)

        pkt.pts *= ist->ts_scale;

    if (pkt.dts != AV_NOPTS_VALUE)

        pkt.dts *= ist->ts_scale;

    if (pkt.dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE &&

        (is->iformat->flags & AVFMT_TS_DISCONT)) {

        int64_t pkt_dts = av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);

        int64_t delta   = pkt_dts - ist->next_dts;

        if ((FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE || pkt_dts + 1 < ist->last_dts) && !copy_ts) {

            ifile->ts_offset -= delta;

            av_log(NULL, AV_LOG_DEBUG,

                   "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",

                   delta, ifile->ts_offset);

            pkt.dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);

            if (pkt.pts != AV_NOPTS_VALUE)

                pkt.pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);

        }

    }

    ret = output_packet(ist, &pkt);

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

    }

discard_packet:

    av_free_packet(&pkt);

    return 0;

}


static int get_int32_le(QEMUFile *f, void *pv, size_t size)

{

    int32_t *cur = pv;

    int32_t loaded;

    qemu_get_sbe32s(f, &loaded);

    if (loaded >= 0 && loaded <= *cur) {

        *cur = loaded;

        return 0;

    }

    return -EINVAL;

}


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

                             int *got_frame, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size       = avpkt->size;

    H264Context *h     = avctx->priv_data;

    AVFrame *pict      = data;

    int buf_index      = 0;

    H264Picture *out;

    int i, out_idx;

    int ret;

    h->flags = avctx->flags;

    h->setup_finished = 0;

    if (h->backup_width != -1) {

        avctx->width    = h->backup_width;

        h->backup_width = -1;

    }

    if (h->backup_height != -1) {

        avctx->height    = h->backup_height;

        h->backup_height = -1;

    }

    if (h->backup_pix_fmt != AV_PIX_FMT_NONE) {

        avctx->pix_fmt    = h->backup_pix_fmt;

        h->backup_pix_fmt = AV_PIX_FMT_NONE;

    }

    ff_h264_unref_picture(h, &h->last_pic_for_ec);

    /* end of stream, output what is still in the buffers */

    if (buf_size == 0) {

 out:

        h->cur_pic_ptr = NULL;

        h->first_field = 0;

        // FIXME factorize this with the output code below

        out     = h->delayed_pic[0];

        out_idx = 0;

        for (i = 1;

             h->delayed_pic[i] &&

             !h->delayed_pic[i]->f->key_frame &&

             !h->delayed_pic[i]->mmco_reset;

             i++)

            if (h->delayed_pic[i]->poc < out->poc) {

                out     = h->delayed_pic[i];

                out_idx = i;

            }

        for (i = out_idx; h->delayed_pic[i]; i++)

            h->delayed_pic[i] = h->delayed_pic[i + 1];

        if (out) {

            out->reference &= ~DELAYED_PIC_REF;

            ret = output_frame(h, pict, out);

            if (ret < 0)

                return ret;

            *got_frame = 1;

        }

        return buf_index;

    }

    if (h->is_avc && av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, NULL)) {

        int side_size;

        uint8_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);

        if (is_extra(side, side_size))

            ff_h264_decode_extradata(h, side, side_size);

    }

    if(h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC && (buf[5]&0x1F) && buf[8]==0x67){

        if (is_extra(buf, buf_size))

            return ff_h264_decode_extradata(h, buf, buf_size);

    }

    buf_index = decode_nal_units(h, buf, buf_size, 0);

    if (buf_index < 0)

        return AVERROR_INVALIDDATA;

    if (!h->cur_pic_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {

        av_assert0(buf_index <= buf_size);

        goto out;

    }

    if (!(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS) && !h->cur_pic_ptr) {

        if (avctx->skip_frame >= AVDISCARD_NONREF ||

            buf_size >= 4 && !memcmp("Q264", buf, 4))

            return buf_size;

        av_log(avctx, AV_LOG_ERROR, "no frame!\n");

        return AVERROR_INVALIDDATA;

    }

    if (!(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS) ||

        (h->mb_y >= h->mb_height && h->mb_height)) {

        if (avctx->flags2 & AV_CODEC_FLAG2_CHUNKS)

            decode_postinit(h, 1);

        if ((ret = ff_h264_field_end(h, &h->slice_ctx[0], 0)) < 0)

            return ret;

        /* Wait for second field. */

        *got_frame = 0;

        if (h->next_output_pic && (

                                   h->next_output_pic->recovered)) {

            if (!h->next_output_pic->recovered)

                h->next_output_pic->f->flags |= AV_FRAME_FLAG_CORRUPT;

            if (!h->avctx->hwaccel &&

                 (h->next_output_pic->field_poc[0] == INT_MAX ||

                  h->next_output_pic->field_poc[1] == INT_MAX)

            ) {

                int p;

                AVFrame *f = h->next_output_pic->f;

                int field = h->next_output_pic->field_poc[0] == INT_MAX;

                uint8_t *dst_data[4];

                int linesizes[4];

                const uint8_t *src_data[4];

                av_log(h->avctx, AV_LOG_DEBUG, "Duplicating field %d to fill missing\n", field);

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

                    dst_data[p] = f->data[p] + (field^1)*f->linesize[p];

                    src_data[p] = f->data[p] +  field   *f->linesize[p];

                    linesizes[p] = 2*f->linesize[p];

                }

                av_image_copy(dst_data, linesizes, src_data, linesizes,

                              f->format, f->width, f->height>>1);

            }

            ret = output_frame(h, pict, h->next_output_pic);

            if (ret < 0)

                return ret;

            *got_frame = 1;

            if (CONFIG_MPEGVIDEO) {

                ff_print_debug_info2(h->avctx, pict, NULL,

                                    h->next_output_pic->mb_type,

                                    h->next_output_pic->qscale_table,

                                    h->next_output_pic->motion_val,

                                    &h->low_delay,

                                    h->mb_width, h->mb_height, h->mb_stride, 1);

            }

        }

    }

    av_assert0(pict->buf[0] || !*got_frame);

    ff_h264_unref_picture(h, &h->last_pic_for_ec);

    return get_consumed_bytes(buf_index, buf_size);

}


static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)

{

    MXFContext *mxf = arg;

    MXFPartition *partition, *tmp_part;

    UID op;

    uint64_t footer_partition;

    uint32_t nb_essence_containers;

    tmp_part = av_realloc_array(mxf->partitions, mxf->partitions_count + 1, sizeof(*mxf->partitions));

    if (!tmp_part)

        return AVERROR(ENOMEM);

    mxf->partitions = tmp_part;

    if (mxf->parsing_backward) {

        /* insert the new partition pack in the middle

         * this makes the entries in mxf->partitions sorted by offset */

        memmove(&mxf->partitions[mxf->last_forward_partition+1],

                &mxf->partitions[mxf->last_forward_partition],

                (mxf->partitions_count - mxf->last_forward_partition)*sizeof(*mxf->partitions));

        partition = mxf->current_partition = &mxf->partitions[mxf->last_forward_partition];

    } else {

        mxf->last_forward_partition++;

        partition = mxf->current_partition = &mxf->partitions[mxf->partitions_count];

    }

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

    mxf->partitions_count++;

    partition->pack_length = avio_tell(pb) - klv_offset + size;

    switch(uid[13]) {

    case 2:

        partition->type = Header;

        break;

    case 3:

        partition->type = BodyPartition;

        break;

    case 4:

        partition->type = Footer;

        break;

    default:

        av_log(mxf->fc, AV_LOG_ERROR, "unknown partition type %i\n", uid[13]);

        return AVERROR_INVALIDDATA;

    }

    /* consider both footers to be closed (there is only Footer and CompleteFooter) */

    partition->closed = partition->type == Footer || !(uid[14] & 1);

    partition->complete = uid[14] > 2;

    avio_skip(pb, 4);

    partition->kag_size = avio_rb32(pb);

    partition->this_partition = avio_rb64(pb);

    partition->previous_partition = avio_rb64(pb);

    footer_partition = avio_rb64(pb);

    partition->header_byte_count = avio_rb64(pb);

    partition->index_byte_count = avio_rb64(pb);

    partition->index_sid = avio_rb32(pb);

    avio_skip(pb, 8);

    partition->body_sid = avio_rb32(pb);

    avio_read(pb, op, sizeof(UID));

    nb_essence_containers = avio_rb32(pb);

    /* some files don'thave FooterPartition set in every partition */

    if (footer_partition) {

        if (mxf->footer_partition && mxf->footer_partition != footer_partition) {

            av_log(mxf->fc, AV_LOG_ERROR,

                   "inconsistent FooterPartition value: %"PRIu64" != %"PRIu64"\n",

                   mxf->footer_partition, footer_partition);

        } else {

            mxf->footer_partition = footer_partition;

        }

    }

    av_dlog(mxf->fc,

            "PartitionPack: ThisPartition = 0x%"PRIX64

            ", PreviousPartition = 0x%"PRIX64", "

            "FooterPartition = 0x%"PRIX64", IndexSID = %i, BodySID = %i\n",

            partition->this_partition,

            partition->previous_partition, footer_partition,

            partition->index_sid, partition->body_sid);

    /* sanity check PreviousPartition if set */

    if (partition->previous_partition &&

        mxf->run_in + partition->previous_partition >= klv_offset) {

        av_log(mxf->fc, AV_LOG_ERROR,

               "PreviousPartition points to this partition or forward\n");

        return AVERROR_INVALIDDATA;

    }

    if      (op[12] == 1 && op[13] == 1) mxf->op = OP1a;

    else if (op[12] == 1 && op[13] == 2) mxf->op = OP1b;

    else if (op[12] == 1 && op[13] == 3) mxf->op = OP1c;

    else if (op[12] == 2 && op[13] == 1) mxf->op = OP2a;

    else if (op[12] == 2 && op[13] == 2) mxf->op = OP2b;

    else if (op[12] == 2 && op[13] == 3) mxf->op = OP2c;

    else if (op[12] == 3 && op[13] == 1) mxf->op = OP3a;

    else if (op[12] == 3 && op[13] == 2) mxf->op = OP3b;

    else if (op[12] == 3 && op[13] == 3) mxf->op = OP3c;

    else if (op[12] == 64&& op[13] == 1) mxf->op = OPSONYOpt;

    else if (op[12] == 0x10) {

        /* SMPTE 390m: "There shall be exactly one essence container"

         * The following block deals with files that violate this, namely:

         * 2011_DCPTEST_24FPS.V.mxf - two ECs, OP1a

         * abcdefghiv016f56415e.mxf - zero ECs, OPAtom, output by Avid AirSpeed */

        if (nb_essence_containers != 1) {

            MXFOP op = nb_essence_containers ? OP1a : OPAtom;

            /* only nag once */

            if (!mxf->op)

                av_log(mxf->fc, AV_LOG_WARNING, "\"OPAtom\" with %u ECs - assuming %s\n",

                       nb_essence_containers, op == OP1a ? "OP1a" : "OPAtom");

            mxf->op = op;

        } else

            mxf->op = OPAtom;

    } else {

        av_log(mxf->fc, AV_LOG_ERROR, "unknown operational pattern: %02xh %02xh - guessing OP1a\n", op[12], op[13]);

        mxf->op = OP1a;

    }

    if (partition->kag_size <= 0 || partition->kag_size > (1 << 20)) {

        av_log(mxf->fc, AV_LOG_WARNING, "invalid KAGSize %i - guessing ", partition->kag_size);

        if (mxf->op == OPSONYOpt)

            partition->kag_size = 512;

        else

            partition->kag_size = 1;

        av_log(mxf->fc, AV_LOG_WARNING, "%i\n", partition->kag_size);

    }

    return 0;

}


void commit_start(BlockDriverState *bs, BlockDriverState *base,

                  BlockDriverState *top, int64_t speed,

                  BlockdevOnError on_error, BlockCompletionFunc *cb,

                  void *opaque, const char *backing_file_str, Error **errp)

{

    CommitBlockJob *s;

    BlockReopenQueue *reopen_queue = NULL;

    int orig_overlay_flags;

    int orig_base_flags;

    BlockDriverState *overlay_bs;

    Error *local_err = NULL;

    assert(top != bs);

    if (top == base) {

        error_setg(errp, "Invalid files for merge: top and base are the same");

        return;

    }

    overlay_bs = bdrv_find_overlay(bs, top);

    if (overlay_bs == NULL) {

        error_setg(errp, "Could not find overlay image for %s:", top->filename);

        return;

    }

    s = block_job_create(&commit_job_driver, bs, speed, cb, opaque, errp);

    if (!s) {

        return;

    }

    orig_base_flags    = bdrv_get_flags(base);

    orig_overlay_flags = bdrv_get_flags(overlay_bs);

    /* convert base & overlay_bs to r/w, if necessary */

    if (!(orig_overlay_flags & BDRV_O_RDWR)) {

        reopen_queue = bdrv_reopen_queue(reopen_queue, overlay_bs, NULL,

                                         orig_overlay_flags | BDRV_O_RDWR);

    }

    if (!(orig_base_flags & BDRV_O_RDWR)) {

        reopen_queue = bdrv_reopen_queue(reopen_queue, base, NULL,

                                         orig_base_flags | BDRV_O_RDWR);

    }

    if (reopen_queue) {

        bdrv_reopen_multiple(reopen_queue, &local_err);

        if (local_err != NULL) {

            error_propagate(errp, local_err);

            block_job_unref(&s->common);

            return;

        }

    }

    s->base = blk_new();

    blk_insert_bs(s->base, base);

    s->top = blk_new();

    blk_insert_bs(s->top, top);

    s->active = bs;

    s->base_flags          = orig_base_flags;

    s->orig_overlay_flags  = orig_overlay_flags;

    s->backing_file_str = g_strdup(backing_file_str);

    s->on_error = on_error;

    s->common.co = qemu_coroutine_create(commit_run);

    trace_commit_start(bs, base, top, s, s->common.co, opaque);

    qemu_coroutine_enter(s->common.co, s);

}


int spapr_tce_dma_read(VIOsPAPRDevice *dev, uint64_t taddr, void *buf,

                       uint32_t size)

{

#ifdef DEBUG_TCE

    fprintf(stderr, "spapr_tce_dma_write taddr=0x%llx size=0x%x\n",

            (unsigned long long)taddr, size);

#endif

    /* Check for bypass */

    if (dev->flags & VIO_PAPR_FLAG_DMA_BYPASS) {

        cpu_physical_memory_read(taddr, buf, size);

        return 0;

    }

    while (size) {

        uint64_t tce;

        uint32_t lsize;

        uint64_t txaddr;

        /* Check if we are in bound */

        if (taddr >= dev->rtce_window_size) {

#ifdef DEBUG_TCE

            fprintf(stderr, "spapr_tce_dma_read out of bounds\n");

#endif

            return H_DEST_PARM;

        }

        tce = dev->rtce_table[taddr >> SPAPR_VIO_TCE_PAGE_SHIFT].tce;

        /* How much til end of page ? */

        lsize = MIN(size, ((~taddr) & SPAPR_VIO_TCE_PAGE_MASK) + 1);

        /* Check TCE */

        if (!(tce & 1)) {

            return H_DEST_PARM;

        }

        /* Translate */

        txaddr = (tce & ~SPAPR_VIO_TCE_PAGE_MASK) |

            (taddr & SPAPR_VIO_TCE_PAGE_MASK);

#ifdef DEBUG_TCE

        fprintf(stderr, " -> write to txaddr=0x%llx, size=0x%x\n",

                (unsigned long long)txaddr, lsize);

#endif

        /* Do it */

        cpu_physical_memory_read(txaddr, buf, lsize);

        buf += lsize;

        taddr += lsize;

        size -= lsize;

    }

    return H_SUCCESS;

}


static av_cold int sunrast_encode_init(AVCodecContext *avctx)

{

    SUNRASTContext *s = avctx->priv_data;

    switch (avctx->coder_type) {

    case FF_CODER_TYPE_RLE:

        s->type = RT_BYTE_ENCODED;

        break;

    case FF_CODER_TYPE_RAW:

        s->type = RT_STANDARD;

        break;

    default:

        av_log(avctx, AV_LOG_ERROR, "invalid coder_type\n");

        return AVERROR(EINVAL);

    }

    avctx->coded_frame = av_frame_alloc();

    if (!avctx->coded_frame)

        return AVERROR(ENOMEM);

    avctx->coded_frame->key_frame = 1;

    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;

    s->maptype                    = RMT_NONE;

    s->maplength                  = 0;

    switch (avctx->pix_fmt) {

    case AV_PIX_FMT_MONOWHITE:

        s->depth = 1;

        break;

    case AV_PIX_FMT_PAL8 :

        s->maptype   = RMT_EQUAL_RGB;

        s->maplength = 3 * 256;

        /* fall-through */

    case AV_PIX_FMT_GRAY8:

        s->depth = 8;

        break;

    case AV_PIX_FMT_BGR24:

        s->depth = 24;

        break;

    default:

        return AVERROR_BUG;

    }

    s->length = avctx->height * (FFALIGN(avctx->width * s->depth, 16) >> 3);

    s->size   = 32 + s->maplength +

                s->length * (s->type == RT_BYTE_ENCODED ? 2 : 1);

    return 0;

}


static void frame_end(MpegEncContext *s)

{

    if (s->unrestricted_mv &&

        s->current_picture.reference &&

        !s->intra_only) {

        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);

        int hshift = desc->log2_chroma_w;

        int vshift = desc->log2_chroma_h;

        s->mpvencdsp.draw_edges(s->current_picture.f->data[0],

                                s->current_picture.f->linesize[0],

                                s->h_edge_pos, s->v_edge_pos,

                                EDGE_WIDTH, EDGE_WIDTH,

                                EDGE_TOP | EDGE_BOTTOM);

        s->mpvencdsp.draw_edges(s->current_picture.f->data[1],

                                s->current_picture.f->linesize[1],

                                s->h_edge_pos >> hshift,

                                s->v_edge_pos >> vshift,

                                EDGE_WIDTH >> hshift,

                                EDGE_WIDTH >> vshift,

                                EDGE_TOP | EDGE_BOTTOM);

        s->mpvencdsp.draw_edges(s->current_picture.f->data[2],

                                s->current_picture.f->linesize[2],

                                s->h_edge_pos >> hshift,

                                s->v_edge_pos >> vshift,

                                EDGE_WIDTH >> hshift,

                                EDGE_WIDTH >> vshift,

                                EDGE_TOP | EDGE_BOTTOM);

    }

    emms_c();

    s->last_pict_type                 = s->pict_type;

    s->last_lambda_for [s->pict_type] = s->current_picture_ptr->f->quality;

    if (s->pict_type!= AV_PICTURE_TYPE_B)

        s->last_non_b_pict_type = s->pict_type;

#if FF_API_CODED_FRAME

FF_DISABLE_DEPRECATION_WARNINGS

    av_frame_copy_props(s->avctx->coded_frame, s->current_picture.f);

FF_ENABLE_DEPRECATION_WARNINGS

#endif

#if FF_API_ERROR_FRAME

FF_DISABLE_DEPRECATION_WARNINGS

    memcpy(s->current_picture.f->error, s->current_picture.encoding_error,

           sizeof(s->current_picture.encoding_error));

FF_ENABLE_DEPRECATION_WARNINGS

#endif

}


static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf)

{

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

    int start_track, format, msf, toclen;

    uint64_t nb_sectors;

    msf = req->cmd.buf[1] & 2;

    format = req->cmd.buf[2] & 0xf;

    start_track = req->cmd.buf[6];

    bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);

    DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);

    nb_sectors /= s->qdev.blocksize / 512;

    switch (format) {

    case 0:

        toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);

        break;

    case 1:

        /* multi session : only a single session defined */

        toclen = 12;

        memset(outbuf, 0, 12);

        outbuf[1] = 0x0a;

        outbuf[2] = 0x01;

        outbuf[3] = 0x01;

        break;

    case 2:

        toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);

        break;

    default:

        return -1;

    }

    if (toclen > req->cmd.xfer) {

        toclen = req->cmd.xfer;

    }

    return toclen;

}


static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)

{

    CharDriverState *chr;

    WinCharState *s;

    chr = qemu_chr_alloc();

    s = g_malloc0(sizeof(WinCharState));

    s->hcom = fd_out;

    chr->opaque = s;

    chr->chr_write = win_chr_write;

    return chr;

}


static av_cold int v4l2_decode_init(AVCodecContext *avctx)

{

    V4L2m2mContext *s = avctx->priv_data;

    V4L2Context *capture = &s->capture;

    V4L2Context *output = &s->output;

    int ret;

    /* if these dimensions are invalid (ie, 0 or too small) an event will be raised

     * by the v4l2 driver; this event will trigger a full pipeline reconfig and

     * the proper values will be retrieved from the kernel driver.

     */

    output->height = capture->height = avctx->coded_height;

    output->width = capture->width = avctx->coded_width;

    output->av_codec_id = avctx->codec_id;

    output->av_pix_fmt  = AV_PIX_FMT_NONE;

    capture->av_codec_id = AV_CODEC_ID_RAWVIDEO;

    capture->av_pix_fmt = avctx->pix_fmt;

    ret = ff_v4l2_m2m_codec_init(avctx);

    if (ret) {

        av_log(avctx, AV_LOG_ERROR, "can't configure decoder\n");

        return ret;

    }

    return v4l2_prepare_decoder(s);

}


static int16_t square_root(int val)

{

    return (ff_sqrt(val << 1) >> 1) & (~1);

}


static int process_audio_header_eacs(AVFormatContext *s)

{

    EaDemuxContext *ea = s->priv_data;

    AVIOContext *pb = s->pb;

    int compression_type;

    ea->sample_rate  = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);

    ea->bytes        = avio_r8(pb);   /* 1=8-bit, 2=16-bit */

    ea->num_channels = avio_r8(pb);

    compression_type = avio_r8(pb);

    avio_skip(pb, 13);

    switch (compression_type) {

    case 0:

        switch (ea->bytes) {

        case 1: ea->audio_codec = CODEC_ID_PCM_S8;    break;

        case 2: ea->audio_codec = CODEC_ID_PCM_S16LE; break;

        break;

    case 1: ea->audio_codec = CODEC_ID_PCM_MULAW; ea->bytes = 1; break;

    case 2: ea->audio_codec = CODEC_ID_ADPCM_IMA_EA_EACS; break;

    default:

        av_log (s, AV_LOG_ERROR, "unsupported stream type; audio compression_type=%i\n", compression_type);

    return 1;


void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd)

{

    NE2000State *s;

    qemu_check_nic_model(nd, "ne2k_isa");

    s = qemu_mallocz(sizeof(NE2000State));

    register_ioport_write(base, 16, 1, ne2000_ioport_write, s);

    register_ioport_read(base, 16, 1, ne2000_ioport_read, s);

    register_ioport_write(base + 0x10, 1, 1, ne2000_asic_ioport_write, s);

    register_ioport_read(base + 0x10, 1, 1, ne2000_asic_ioport_read, s);

    register_ioport_write(base + 0x10, 2, 2, ne2000_asic_ioport_write, s);

    register_ioport_read(base + 0x10, 2, 2, ne2000_asic_ioport_read, s);

    register_ioport_write(base + 0x1f, 1, 1, ne2000_reset_ioport_write, s);

    register_ioport_read(base + 0x1f, 1, 1, ne2000_reset_ioport_read, s);

    s->irq = irq;

    memcpy(s->macaddr, nd->macaddr, 6);

    ne2000_reset(s);

    s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,

                                 ne2000_receive, ne2000_can_receive, s);

    qemu_format_nic_info_str(s->vc, s->macaddr);

    register_savevm("ne2000", -1, 2, ne2000_save, ne2000_load, s);

}


static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid,

                           unsigned int pid)

{

    struct Program *p = get_program(ts, programid);

    int i;

    if (!p)

        return;

    if (p->nb_pids >= MAX_PIDS_PER_PROGRAM)

        return;

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

        if (p->pids[i] == pid)

            return;

    p->pids[p->nb_pids++] = pid;

}


static int calculate_geometry(int64_t total_sectors, uint16_t* cyls,

    uint8_t* heads, uint8_t* secs_per_cyl)

{

    uint32_t cyls_times_heads;

    if (total_sectors > 65535 * 16 * 255)

        return -EFBIG;

    if (total_sectors > 65535 * 16 * 63) {

        *secs_per_cyl = 255;

        *heads = 16;

        cyls_times_heads = total_sectors / *secs_per_cyl;

    } else {

        *secs_per_cyl = 17;

        cyls_times_heads = total_sectors / *secs_per_cyl;

        *heads = (cyls_times_heads + 1023) / 1024;

        if (*heads < 4)

            *heads = 4;

        if (cyls_times_heads >= (*heads * 1024) || *heads > 16) {

            *secs_per_cyl = 31;

            *heads = 16;

            cyls_times_heads = total_sectors / *secs_per_cyl;

        }

        if (cyls_times_heads >= (*heads * 1024)) {

            *secs_per_cyl = 63;

            *heads = 16;

            cyls_times_heads = total_sectors / *secs_per_cyl;

        }

    }

    // Note: Rounding up deviates from the Virtual PC behaviour

    // However, we need this to avoid truncating images in qemu-img convert

    *cyls = (cyls_times_heads + *heads - 1) / *heads;

    return 0;

}


static inline void gen_arm_shift_reg(TCGv var, int shiftop,

                                     TCGv shift, int flags)

{

    if (flags) {

        switch (shiftop) {

        case 0: gen_helper_shl_cc(var, var, shift); break;

        case 1: gen_helper_shr_cc(var, var, shift); break;

        case 2: gen_helper_sar_cc(var, var, shift); break;

        case 3: gen_helper_ror_cc(var, var, shift); break;

        }

    } else {

        switch (shiftop) {

        case 0: gen_helper_shl(var, var, shift); break;

        case 1: gen_helper_shr(var, var, shift); break;

        case 2: gen_helper_sar(var, var, shift); break;

        case 3: tcg_gen_andi_i32(shift, shift, 0x1f);

                tcg_gen_rotr_i32(var, var, shift); break;

        }

    }

    dead_tmp(shift);

}


static inline void RENAME(bgr15ToY)(uint8_t *dst, uint8_t *src, int width)

{

	int i;

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

	{

		int d= ((uint16_t*)src)[i];

		int b= d&0x1F;

		int g= (d>>5)&0x1F;

		int r= (d>>10)&0x1F;

		dst[i]= ((RY*r + GY*g + BY*b)>>(RGB2YUV_SHIFT-3)) + 16;

	}

}


static void decode_gain_info(GetBitContext *gb, int *gaininfo)

{

    int i, n;

    while (get_bits1(gb)) {

        /* NOTHING */

    }

    n = get_bits_count(gb) - 1;     // amount of elements*2 to update

    i = 0;

    while (n--) {

        int index = get_bits(gb, 3);

        int gain = get_bits1(gb) ? get_bits(gb, 4) - 7 : -1;

        while (i <= index)

            gaininfo[i++] = gain;

    }

    while (i <= 8)

        gaininfo[i++] = 0;

}


static int decode_b_picture_primary_header(VC9Context *v)

{

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

    int pqindex;

    /* Prolog common to all frametypes should be done in caller */

    if (v->profile == PROFILE_SIMPLE)

    {

        av_log(v->s.avctx, AV_LOG_ERROR, "Found a B frame while in Simple Profile!\n");

        return FRAME_SKIPED;

    }

    v->bfraction = vc9_bfraction_lut[get_vlc2(gb, vc9_bfraction_vlc.table,

                                              VC9_BFRACTION_VLC_BITS, 2)];

    if (v->bfraction < -1)

    {

        av_log(v->s.avctx, AV_LOG_ERROR, "Invalid BFRaction\n");

        return FRAME_SKIPED;

    }

    else if (!v->bfraction)

    {

        /* We actually have a BI frame */

        v->s.pict_type = BI_TYPE;

        v->buffer_fullness = get_bits(gb, 7);

    }

    /* Read the quantization stuff */

    pqindex = get_bits(gb, 5);

    if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)

        v->pq = pquant_table[0][pqindex];

    else

    {

        v->pq = pquant_table[v->quantizer_mode-1][pqindex];

    }

    if (pqindex < 9) v->halfpq = get_bits(gb, 1);

    if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)

        v->pquantizer = get_bits(gb, 1);

    if (v->profile > PROFILE_MAIN)

    {

        if (v->postprocflag) v->postproc = get_bits(gb, 2);

        if (v->extended_mv == 1 && v->s.pict_type != BI_TYPE)

            v->mvrange = get_prefix(gb, 0, 3);

    }

    else

    {

        if (v->extended_mv == 1)

            v->mvrange = get_prefix(gb, 0, 3);

    }

    /* Read the MV mode */

    if (v->s.pict_type != BI_TYPE)

    {

        v->mv_mode = get_bits(gb, 1);

        if (v->pq < 13)

        {

            if (!v->mv_mode)

            {

                v->mv_mode = get_bits(gb, 2);

                if (v->mv_mode)

                av_log(v->s.avctx, AV_LOG_ERROR,

                       "mv_mode for lowquant B frame was %i\n", v->mv_mode);

            }

        }

        else

        {

            if (!v->mv_mode)

            {

                if (get_bits(gb, 1))

                     av_log(v->s.avctx, AV_LOG_ERROR,

                            "mv_mode for highquant B frame was %i\n", v->mv_mode);

            }

            v->mv_mode = 1-v->mv_mode; //To match (pq < 13) mapping

        }

    }

    return 0;

}


static inline void check_privileged(DisasContext *s)

{

    if (s->tb->flags & (PSW_MASK_PSTATE >> 32)) {

        gen_program_exception(s, PGM_PRIVILEGED);

    }

}


static int decode_p_mbs(VC9Context *v)

{

    MpegEncContext *s = &v->s;

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

    int current_mb = 0, i; /* MB/Block Position info */

    uint8_t cbpcy[4], previous_cbpcy[4], predicted_cbpcy,

        *p_cbpcy /* Pointer to skip some math */;

    int hybrid_pred; /* Prediction types */

    int mv_mode_bit = 0;

    int mqdiff, mquant; /* MB quantization */

    int ttmb; /* MB Transform type */

    static const int size_table[6] = { 0, 2, 3, 4, 5, 8 },

        offset_table[6] = { 0, 1, 3, 7, 15, 31 };

        int mb_has_coeffs = 1; /* last_flag */

    int dmv_x, dmv_y; /* Differential MV components */

    int k_x, k_y; /* Long MV fixed bitlength */

    int hpel_flag; /* Some MB properties */

    int index, index1; /* LUT indices */

    int val, sign; /* MVDATA temp values */

    /* Select ttmb table depending on pq */

    if (v->pq < 5) v->ttmb_vlc = &vc9_ttmb_vlc[0];

    else if (v->pq < 13) v->ttmb_vlc = &vc9_ttmb_vlc[1];

    else v->ttmb_vlc = &vc9_ttmb_vlc[2];

    /* Select proper long MV range */

    switch (v->mvrange)

    {

    case 1: k_x = 10; k_y = 9; break;

    case 2: k_x = 12; k_y = 10; break;

    case 3: k_x = 13; k_y = 11; break;

    default: /*case 0 too */ k_x = 9; k_y = 8; break;

    }

    hpel_flag = v->mv_mode & 1; //MV_PMODE is HPEL

    k_x -= hpel_flag;

    k_y -= hpel_flag;

    /* Reset CBPCY predictors */

    memset(v->previous_line_cbpcy, 0, s->mb_stride<<2);

    for (s->mb_y=0; s->mb_y<s->mb_height; s->mb_y++)

    {

        /* Init CBPCY for line */

        *((uint32_t*)previous_cbpcy) = 0x00000000;

        p_cbpcy = v->previous_line_cbpcy+4;

        for (s->mb_x=0; s->mb_x<s->mb_width; s->mb_x++, p_cbpcy += 4)

        {

            if (v->mv_type_mb_plane.is_raw)

                v->mv_type_mb_plane.data[current_mb] = get_bits(gb, 1);

            if (v->skip_mb_plane.is_raw)

                v->skip_mb_plane.data[current_mb] = get_bits(gb, 1);

            if (!mv_mode_bit) /* 1MV mode */

            {

                if (!v->skip_mb_plane.data[current_mb])

                {

                    GET_MVDATA(dmv_x, dmv_y);

                    /* hybrid mv pred, 8.3.5.3.4 */

                    if (v->mv_mode == MV_PMODE_1MV ||

                        v->mv_mode == MV_PMODE_MIXED_MV)

                        hybrid_pred = get_bits(gb, 1);

                    if (s->mb_intra && !mb_has_coeffs)

                    {

                        GET_MQUANT();

                        s->ac_pred = get_bits(gb, 1);

                    }

                    else if (mb_has_coeffs)

                    {

                        if (s->mb_intra) s->ac_pred = get_bits(gb, 1);

                        predicted_cbpcy = get_vlc2(gb, v->cbpcy_vlc->table, VC9_CBPCY_P_VLC_BITS, 2);

                        cbpcy[0] = (p_cbpcy[-1] == p_cbpcy[2]) ? previous_cbpcy[1] : p_cbpcy[2];

                        cbpcy[0] ^= ((predicted_cbpcy>>5)&0x01);

                        cbpcy[1] = (p_cbpcy[2] == p_cbpcy[3]) ? cbpcy[0] : p_cbpcy[3];

                        cbpcy[1] ^= ((predicted_cbpcy>>4)&0x01);

                        cbpcy[2] = (previous_cbpcy[1] == cbpcy[0]) ? previous_cbpcy[3] : cbpcy[0];

                        cbpcy[2] ^= ((predicted_cbpcy>>3)&0x01);

                        cbpcy[3] = (cbpcy[1] == cbpcy[0]) ? cbpcy[2] : cbpcy[1];

                        cbpcy[3] ^= ((predicted_cbpcy>>2)&0x01);

                        //GET_CBPCY(v->cbpcy_vlc->table, VC9_CBPCY_P_VLC_BITS);

                        GET_MQUANT();

                    }

                    if (!v->ttmbf)

                        ttmb = get_vlc2(gb, v->ttmb_vlc->table,

                                            VC9_TTMB_VLC_BITS, 12);

                    /* TODO: decode blocks from that mb wrt cbpcy */

                }

                else //Skipped

                {

                    /* hybrid mv pred, 8.3.5.3.4 */

                    if (v->mv_mode == MV_PMODE_1MV ||

                        v->mv_mode == MV_PMODE_MIXED_MV)

                        hybrid_pred = get_bits(gb, 1);

                }

            } //1MV mode

            else //4MV mode

            {

              if (!v->skip_mb_plane.data[current_mb] /* unskipped MB */)

                {

                    /* Get CBPCY */

                    GET_CBPCY(v->cbpcy_vlc->table, VC9_CBPCY_P_VLC_BITS);

                    for (i=0; i<4; i++) //For all 4 Y blocks

                    {

                        if (cbpcy[i] /* cbpcy set for this block */)

                        {

                            GET_MVDATA(dmv_x, dmv_y);

                        }

                        if (v->mv_mode == MV_PMODE_MIXED_MV /* Hybrid pred */)

                            hybrid_pred = get_bits(gb, 1);

                        GET_MQUANT();

                        if (s->mb_intra /* One of the 4 blocks is intra */ &&

                            index /* non-zero pred for that block */)

                            s->ac_pred = get_bits(gb, 1);

                        if (!v->ttmbf)

                            ttmb = get_vlc2(gb, v->ttmb_vlc->table,

                                            VC9_TTMB_VLC_BITS, 12);

                        /* TODO: Process blocks wrt cbpcy */

                    }

                }

                else //Skipped MB

                {

                    for (i=0; i<4; i++) //All 4 Y blocks

                    {

                        if (v->mv_mode == MV_PMODE_MIXED_MV /* Hybrid pred */)

                            hybrid_pred = get_bits(gb, 1);

                        /* TODO: do something */

                    }

                }

            }

            /* Update for next block */

#if TRACE > 2

            av_log(s->avctx, AV_LOG_DEBUG, "Block %4i: p_cbpcy=%i%i%i%i, previous_cbpcy=%i%i%i%i,"

                   " cbpcy=%i%i%i%i\n", current_mb,

                   p_cbpcy[0], p_cbpcy[1], p_cbpcy[2], p_cbpcy[3],

                   previous_cbpcy[0], previous_cbpcy[1], previous_cbpcy[2], previous_cbpcy[3],

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

#endif

            *((uint32_t*)p_cbpcy) = *((uint32_t*)previous_cbpcy);

            *((uint32_t*)previous_cbpcy) = *((uint32_t*)cbpcy);

            current_mb++;

        }

    }

    return 0;

}


static void fsl_imx25_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);
    dc->realize = fsl_imx25_realize;
}


SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)

{

    SwsFunc t = NULL;

#if (HAVE_MMX2 || HAVE_MMX) && CONFIG_GPL

     t = ff_yuv2rgb_init_mmx(c);

#endif

#if HAVE_VIS

    t = ff_yuv2rgb_init_vis(c);

#endif

#if CONFIG_MLIB

    t = ff_yuv2rgb_init_mlib(c);

#endif

#if HAVE_ALTIVEC && CONFIG_GPL

    if (c->flags & SWS_CPU_CAPS_ALTIVEC)

        t = ff_yuv2rgb_init_altivec(c);

#endif

#if ARCH_BFIN

    if (c->flags & SWS_CPU_CAPS_BFIN)

        t = ff_yuv2rgb_get_func_ptr_bfin(c);

#endif

    if (t)

        return t;

    av_log(c, AV_LOG_WARNING, "No accelerated colorspace conversion found.\n");

    switch (c->dstFormat) {

    case PIX_FMT_RGB48BE:

    case PIX_FMT_RGB48LE:    return yuv2rgb_c_48;

    case PIX_FMT_ARGB:

    case PIX_FMT_ABGR:       if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) return yuva2argb_c;

    case PIX_FMT_RGBA:

    case PIX_FMT_BGRA:       return (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) ? yuva2rgba_c : yuv2rgb_c_32;

    case PIX_FMT_RGB24:      return yuv2rgb_c_24_rgb;

    case PIX_FMT_BGR24:      return yuv2rgb_c_24_bgr;

    case PIX_FMT_RGB565:

    case PIX_FMT_BGR565:

    case PIX_FMT_RGB555:

    case PIX_FMT_BGR555:     return yuv2rgb_c_16;

    case PIX_FMT_RGB8:

    case PIX_FMT_BGR8:       return yuv2rgb_c_8_ordered_dither;

    case PIX_FMT_RGB4:

    case PIX_FMT_BGR4:       return yuv2rgb_c_4_ordered_dither;

    case PIX_FMT_RGB4_BYTE:

    case PIX_FMT_BGR4_BYTE:  return yuv2rgb_c_4b_ordered_dither;

    case PIX_FMT_MONOBLACK:  return yuv2rgb_c_1_ordered_dither;

    default:

        assert(0);

    }

    return NULL;

}


static inline void celt_encode_pulses(OpusRangeCoder *rc, int *y, uint32_t N, uint32_t K)

{

    ff_opus_rc_enc_uint(rc, celt_icwrsi(N, y), CELT_PVQ_V(N, K));

}


static void gen_partset_reg(int opsize, TCGv reg, TCGv val)

{

    TCGv tmp;

    switch (opsize) {

    case OS_BYTE:

        tcg_gen_andi_i32(reg, reg, 0xffffff00);

        tmp = tcg_temp_new();

        tcg_gen_ext8u_i32(tmp, val);

        tcg_gen_or_i32(reg, reg, tmp);

        break;

    case OS_WORD:

        tcg_gen_andi_i32(reg, reg, 0xffff0000);

        tmp = tcg_temp_new();

        tcg_gen_ext16u_i32(tmp, val);

        tcg_gen_or_i32(reg, reg, tmp);

        break;

    case OS_LONG:

    case OS_SINGLE:

        tcg_gen_mov_i32(reg, val);

        break;

    default:

        qemu_assert(0, "Bad operand size");

        break;

    }

}


PCIBus *pci_apb_init(target_phys_addr_t special_base,

                     target_phys_addr_t mem_base,

                     qemu_irq *pic, PCIBus **bus2, PCIBus **bus3)

{

    DeviceState *dev;

    SysBusDevice *s;

    APBState *d;

    /* Ultrasparc PBM main bus */

    dev = qdev_create(NULL, "pbm");

    qdev_init(dev);

    s = sysbus_from_qdev(dev);

    /* apb_config */

    sysbus_mmio_map(s, 0, special_base + 0x2000ULL);

    /* pci_ioport */

    sysbus_mmio_map(s, 1, special_base + 0x2000000ULL);

    /* mem_config: XXX size should be 4G-prom */

    sysbus_mmio_map(s, 2, special_base + 0x1000000ULL);

    /* mem_data */

    sysbus_mmio_map(s, 3, mem_base);

    d = FROM_SYSBUS(APBState, s);

    d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",

                                         pci_apb_set_irq, pci_pbm_map_irq, pic,

                                         0, 32);

    pci_create_simple(d->host_state.bus, 0, "pbm");

    /* APB secondary busses */

    *bus2 = pci_bridge_init(d->host_state.bus, 8, PCI_VENDOR_ID_SUN,

                            PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq,

                            "Advanced PCI Bus secondary bridge 1");

    *bus3 = pci_bridge_init(d->host_state.bus, 9, PCI_VENDOR_ID_SUN,

                            PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq,

                            "Advanced PCI Bus secondary bridge 2");

    return d->host_state.bus;

}


static void pc_numa_cpu(const void *data)

{

    char *cli;

    QDict *resp;

    QList *cpus;

    const QObject *e;

    cli = make_cli(data, "-cpu pentium -smp 8,sockets=2,cores=2,threads=2 "

        "-numa node,nodeid=0 -numa node,nodeid=1 "

        "-numa cpu,node-id=1,socket-id=0 "

        "-numa cpu,node-id=0,socket-id=1,core-id=0 "

        "-numa cpu,node-id=0,socket-id=1,core-id=1,thread-id=0 "

        "-numa cpu,node-id=1,socket-id=1,core-id=1,thread-id=1");

    qtest_start(cli);

    cpus = get_cpus(&resp);

    g_assert(cpus);

    while ((e = qlist_pop(cpus))) {

        QDict *cpu, *props;

        int64_t socket, core, thread, node;

        cpu = qobject_to_qdict(e);

        g_assert(qdict_haskey(cpu, "props"));

        props = qdict_get_qdict(cpu, "props");

        g_assert(qdict_haskey(props, "node-id"));

        node = qdict_get_int(props, "node-id");

        g_assert(qdict_haskey(props, "socket-id"));

        socket = qdict_get_int(props, "socket-id");

        g_assert(qdict_haskey(props, "core-id"));

        core = qdict_get_int(props, "core-id");

        g_assert(qdict_haskey(props, "thread-id"));

        thread = qdict_get_int(props, "thread-id");

        if (socket == 0) {

            g_assert_cmpint(node, ==, 1);

        } else if (socket == 1 && core == 0) {

            g_assert_cmpint(node, ==, 0);

        } else if (socket == 1 && core == 1 && thread == 0) {

            g_assert_cmpint(node, ==, 0);

        } else if (socket == 1 && core == 1 && thread == 1) {

            g_assert_cmpint(node, ==, 1);

        } else {

            g_assert(false);

        }

    }

    QDECREF(resp);

    qtest_end();

    g_free(cli);

}


static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)

{

    CPUState *cs = CPU(cpu);

    CPUX86State *env = &cpu->env;

    VAPICHandlers *handlers;

    uint8_t opcode[2];

    uint32_t imm32 = 0;

    target_ulong current_pc = 0;

    target_ulong current_cs_base = 0;

    uint32_t current_flags = 0;

    if (smp_cpus == 1) {

        handlers = &s->rom_state.up;

    } else {

        handlers = &s->rom_state.mp;

    }

    if (!kvm_enabled()) {

        cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base,

                             &current_flags);

        /* Account this instruction, because we will exit the tb.

           This is the first instruction in the block. Therefore

           there is no need in restoring CPU state. */

        if (use_icount) {

            --cs->icount_decr.u16.low;

        }

    }

    pause_all_vcpus();

    cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0);

    switch (opcode[0]) {

    case 0x89: /* mov r32 to r/m32 */

        patch_byte(cpu, ip, 0x50 + modrm_reg(opcode[1]));  /* push reg */

        patch_call(s, cpu, ip + 1, handlers->set_tpr);

        break;

    case 0x8b: /* mov r/m32 to r32 */

        patch_byte(cpu, ip, 0x90);

        patch_call(s, cpu, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);

        break;

    case 0xa1: /* mov abs to eax */

        patch_call(s, cpu, ip, handlers->get_tpr[0]);

        break;

    case 0xa3: /* mov eax to abs */

        patch_call(s, cpu, ip, handlers->set_tpr_eax);

        break;

    case 0xc7: /* mov imm32, r/m32 (c7/0) */

        patch_byte(cpu, ip, 0x68);  /* push imm32 */

        cpu_memory_rw_debug(cs, ip + 6, (void *)&imm32, sizeof(imm32), 0);

        cpu_memory_rw_debug(cs, ip + 1, (void *)&imm32, sizeof(imm32), 1);

        patch_call(s, cpu, ip + 5, handlers->set_tpr);

        break;

    case 0xff: /* push r/m32 */

        patch_byte(cpu, ip, 0x50); /* push eax */

        patch_call(s, cpu, ip + 1, handlers->get_tpr_stack);

        break;

    default:

        abort();

    }

    resume_all_vcpus();

    if (!kvm_enabled()) {

        /* tb_lock will be reset when cpu_loop_exit_noexc longjmps

         * back into the cpu_exec loop. */

        tb_lock();

        tb_gen_code(cs, current_pc, current_cs_base, current_flags, 1);

        cpu_loop_exit_noexc(cs);

    }

}


static int vc9_decode_frame(AVCodecContext *avctx,

                            void *data, int *data_size,

                            uint8_t *buf, int buf_size)

{

    VC9Context *v = avctx->priv_data;

    MpegEncContext *s = &v->s;

    int ret = FRAME_SKIPED, len, start_code;

    AVFrame *pict = data;

    uint8_t *tmp_buf;

    v->s.avctx = avctx;

    //buf_size = 0 -> last frame

    if (!buf_size) return 0;

    len = avpicture_get_size(avctx->pix_fmt, avctx->width,

                             avctx->height);

    tmp_buf = (uint8_t *)av_mallocz(len);

    avpicture_fill((AVPicture *)pict, tmp_buf, avctx->pix_fmt,

                   avctx->width, avctx->height);

    if (avctx->codec_id == CODEC_ID_VC9)

    {

#if 0

	// search for IDU's

	// FIXME

	uint32_t scp = 0;

	int scs = 0, i = 0;

	while (i < buf_size)

	{

	    for (; i < buf_size && scp != 0x000001; i++)

		scp = ((scp<<8)|buf[i])&0xffffff;

	    if (scp != 0x000001)

		break; // eof ?

	    scs = buf[i++];

	    init_get_bits(gb, buf+i, (buf_size-i)*8);

	    switch(scs)

	    {

            case 0x0A: //Sequence End Code

                return 0;

            case 0x0B: //Slice Start Code

                av_log(avctx, AV_LOG_ERROR, "Slice coding not supported\n");

                return -1;

            case 0x0C: //Field start code

                av_log(avctx, AV_LOG_ERROR, "Interlaced coding not supported\n");

                return -1;

            case 0x0D: //Frame start code

                break;

            case 0x0E: //Entry point Start Code

                if (v->profile <= MAIN_PROFILE)

                    av_log(avctx, AV_LOG_ERROR,

                           "Found an entry point in profile %i\n", v->profile);

                advanced_entry_point_process(avctx, gb);

                break;

            case 0x0F: //Sequence header Start Code

                decode_sequence_header(avctx, gb);

                break;

            default:

                av_log(avctx, AV_LOG_ERROR,

                       "Unsupported IDU suffix %lX\n", scs);

            }

	    i += get_bits_count(gb)*8;

	}

#else

	av_abort();

#endif

    }

    else

        init_get_bits(&v->s.gb, buf, buf_size*8);

    s->flags= avctx->flags;

    s->flags2= avctx->flags2;

    /* no supplementary picture */

    if (buf_size == 0) {

        /* special case for last picture */

        if (s->low_delay==0 && s->next_picture_ptr) {

            *pict= *(AVFrame*)s->next_picture_ptr;

            s->next_picture_ptr= NULL;

            *data_size = sizeof(AVFrame);

        }

        return 0;

    }

    //No IDU - we mimic ff_h263_decode_frame

    s->bitstream_buffer_size=0;

    if (!s->context_initialized) {

        if (MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix

            return -1;

    }

    //we need to set current_picture_ptr before reading the header, otherwise we cant store anyting im there

    if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){

        s->current_picture_ptr= &s->picture[ff_find_unused_picture(s, 0)];

    }

#if HAS_ADVANCED_PROFILE

    if (v->profile > PROFILE_MAIN)

        ret= advanced_decode_picture_primary_header(v);

    else

#endif

        ret= standard_decode_picture_primary_header(v);

    if (ret == FRAME_SKIPED) return buf_size;

    /* skip if the header was thrashed */

    if (ret < 0){

        av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");

        return -1;

    }

    //No bug workaround yet, no DCT conformance

    //WMV9 does have resized images

    if (v->profile <= PROFILE_MAIN && v->multires){

        //Parse context stuff in here, don't know how appliable it is

    }

    //Not sure about context initialization

    // for hurry_up==5

    s->current_picture.pict_type= s->pict_type;

    s->current_picture.key_frame= s->pict_type == I_TYPE;

    /* skip b frames if we dont have reference frames */

    if(s->last_picture_ptr==NULL && (s->pict_type==B_TYPE || s->dropable))

        return buf_size; //FIXME simulating all buffer consumed

    /* skip b frames if we are in a hurry */

    if(avctx->hurry_up && s->pict_type==B_TYPE)

        return buf_size; //FIXME simulating all buffer consumed

    /* skip everything if we are in a hurry>=5 */

    if(avctx->hurry_up>=5)

        return buf_size; //FIXME simulating all buffer consumed

    if(s->next_p_frame_damaged){

        if(s->pict_type==B_TYPE)

            return buf_size; //FIXME simulating all buffer consumed

        else

            s->next_p_frame_damaged=0;

    }

    if(MPV_frame_start(s, avctx) < 0)

        return -1;

    ff_er_frame_start(s);

    //wmv9 may or may not have skip bits

#if HAS_ADVANCED_PROFILE

    if (v->profile > PROFILE_MAIN)

        ret= advanced_decode_picture_secondary_header(v);

    else

#endif

        ret = standard_decode_picture_secondary_header(v);

    if (ret<0) return FRAME_SKIPED; //FIXME Non fatal for now

    //We consider the image coded in only one slice

#if HAS_ADVANCED_PROFILE

    if (v->profile > PROFILE_MAIN)

    {

        switch(s->pict_type)

        {

            case I_TYPE: ret = advanced_decode_i_mbs(v); break;

            case P_TYPE: ret = decode_p_mbs(v); break;

            case B_TYPE:

            case BI_TYPE: ret = decode_b_mbs(v); break;

            default: ret = FRAME_SKIPED;

        }

        if (ret == FRAME_SKIPED) return buf_size; //We ignore for now failures

    }

    else

#endif

    {

        switch(s->pict_type)

        {

            case I_TYPE: ret = standard_decode_i_mbs(v); break;

            case P_TYPE: ret = decode_p_mbs(v); break;

            case B_TYPE:

            case BI_TYPE: ret = decode_b_mbs(v); break;

            default: ret = FRAME_SKIPED;

        }

        if (ret == FRAME_SKIPED) return buf_size;

    }

    ff_er_frame_end(s);

    MPV_frame_end(s);

    assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type);

    assert(s->current_picture.pict_type == s->pict_type);

    if(s->pict_type==B_TYPE || s->low_delay){

        *pict= *(AVFrame*)&s->current_picture;

        ff_print_debug_info(s, pict);

    } else {

        *pict= *(AVFrame*)&s->last_picture;

        if(pict)

            ff_print_debug_info(s, pict);

    }

    /* Return the Picture timestamp as the frame number */

    /* we substract 1 because it is added on utils.c    */

    avctx->frame_number = s->picture_number - 1;

    /* dont output the last pic after seeking */

    if(s->last_picture_ptr || s->low_delay)

        *data_size = sizeof(AVFrame);

    av_log(avctx, AV_LOG_DEBUG, "Consumed %i/%i bits\n",

           get_bits_count(&s->gb), buf_size*8);

    /* Fake consumption of all data */

    *data_size = len;

    return buf_size; //Number of bytes consumed

}