void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth, const int chroma_format_idc)

{

#if HAVE_YASM

    int mm_flags = av_get_cpu_flags();

    if (bit_depth == 8) {

        if (mm_flags & AV_CPU_FLAG_MMX) {

            h->pred16x16[VERT_PRED8x8         ] = ff_pred16x16_vertical_mmx;

            h->pred16x16[HOR_PRED8x8          ] = ff_pred16x16_horizontal_mmx;

            if (chroma_format_idc == 1) {

                h->pred8x8  [VERT_PRED8x8     ] = ff_pred8x8_vertical_mmx;

                h->pred8x8  [HOR_PRED8x8      ] = ff_pred8x8_horizontal_mmx;

            }

            if (codec_id == AV_CODEC_ID_VP8) {

                h->pred16x16[PLANE_PRED8x8    ] = ff_pred16x16_tm_vp8_mmx;

                h->pred8x8  [PLANE_PRED8x8    ] = ff_pred8x8_tm_vp8_mmx;

                h->pred4x4  [TM_VP8_PRED      ] = ff_pred4x4_tm_vp8_mmx;

            } else {

                if (chroma_format_idc == 1)

                    h->pred8x8  [PLANE_PRED8x8] = ff_pred8x8_plane_mmx;

                if (codec_id == AV_CODEC_ID_SVQ3) {

                    if (mm_flags & AV_CPU_FLAG_CMOV)

                        h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_mmx;

                } else if (codec_id == AV_CODEC_ID_RV40) {

                    h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_rv40_mmx;

                } else {

                    h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_h264_mmx;

                }

            }

        }

        if (mm_flags & AV_CPU_FLAG_MMXEXT) {

            h->pred16x16[HOR_PRED8x8            ] = ff_pred16x16_horizontal_mmx2;

            h->pred16x16[DC_PRED8x8             ] = ff_pred16x16_dc_mmx2;

            if (chroma_format_idc == 1)

                h->pred8x8[HOR_PRED8x8          ] = ff_pred8x8_horizontal_mmx2;

            h->pred8x8l [TOP_DC_PRED            ] = ff_pred8x8l_top_dc_mmxext;

            h->pred8x8l [DC_PRED                ] = ff_pred8x8l_dc_mmxext;

            h->pred8x8l [HOR_PRED               ] = ff_pred8x8l_horizontal_mmxext;

            h->pred8x8l [VERT_PRED              ] = ff_pred8x8l_vertical_mmxext;

            h->pred8x8l [DIAG_DOWN_RIGHT_PRED   ] = ff_pred8x8l_down_right_mmxext;

            h->pred8x8l [VERT_RIGHT_PRED        ] = ff_pred8x8l_vertical_right_mmxext;

            h->pred8x8l [HOR_UP_PRED            ] = ff_pred8x8l_horizontal_up_mmxext;

            h->pred8x8l [DIAG_DOWN_LEFT_PRED    ] = ff_pred8x8l_down_left_mmxext;

            h->pred8x8l [HOR_DOWN_PRED          ] = ff_pred8x8l_horizontal_down_mmxext;

            h->pred4x4  [DIAG_DOWN_RIGHT_PRED   ] = ff_pred4x4_down_right_mmxext;

            h->pred4x4  [VERT_RIGHT_PRED        ] = ff_pred4x4_vertical_right_mmxext;

            h->pred4x4  [HOR_DOWN_PRED          ] = ff_pred4x4_horizontal_down_mmxext;

            h->pred4x4  [DC_PRED                ] = ff_pred4x4_dc_mmxext;

            if (codec_id == AV_CODEC_ID_VP8 || codec_id == AV_CODEC_ID_H264) {

                h->pred4x4  [DIAG_DOWN_LEFT_PRED] = ff_pred4x4_down_left_mmxext;

            }

            if (codec_id == AV_CODEC_ID_SVQ3 || codec_id == AV_CODEC_ID_H264) {

                h->pred4x4  [VERT_LEFT_PRED     ] = ff_pred4x4_vertical_left_mmxext;

            }

            if (codec_id != AV_CODEC_ID_RV40) {

                h->pred4x4  [HOR_UP_PRED        ] = ff_pred4x4_horizontal_up_mmxext;

            }

            if (codec_id == AV_CODEC_ID_SVQ3 || codec_id == AV_CODEC_ID_H264) {

                if (chroma_format_idc == 1) {

                    h->pred8x8[TOP_DC_PRED8x8   ] = ff_pred8x8_top_dc_mmxext;

                    h->pred8x8[DC_PRED8x8       ] = ff_pred8x8_dc_mmxext;

                }

            }

            if (codec_id == AV_CODEC_ID_VP8) {

                h->pred16x16[PLANE_PRED8x8      ] = ff_pred16x16_tm_vp8_mmx2;

                h->pred8x8  [DC_PRED8x8         ] = ff_pred8x8_dc_rv40_mmxext;

                h->pred8x8  [PLANE_PRED8x8      ] = ff_pred8x8_tm_vp8_mmx2;

                h->pred4x4  [TM_VP8_PRED        ] = ff_pred4x4_tm_vp8_mmx2;

                h->pred4x4  [VERT_PRED          ] = ff_pred4x4_vertical_vp8_mmxext;

            } else {

                if (chroma_format_idc == 1)

                    h->pred8x8  [PLANE_PRED8x8] = ff_pred8x8_plane_mmx2;

                if (codec_id == AV_CODEC_ID_SVQ3) {

                    h->pred16x16[PLANE_PRED8x8  ] = ff_pred16x16_plane_svq3_mmx2;

                } else if (codec_id == AV_CODEC_ID_RV40) {

                    h->pred16x16[PLANE_PRED8x8  ] = ff_pred16x16_plane_rv40_mmx2;

                } else {

                    h->pred16x16[PLANE_PRED8x8  ] = ff_pred16x16_plane_h264_mmx2;

                }

            }

        }

        if (mm_flags & AV_CPU_FLAG_SSE) {

            h->pred16x16[VERT_PRED8x8] = ff_pred16x16_vertical_sse;

        }

        if (mm_flags & AV_CPU_FLAG_SSE2) {

            h->pred16x16[DC_PRED8x8           ] = ff_pred16x16_dc_sse2;

            h->pred8x8l [DIAG_DOWN_LEFT_PRED  ] = ff_pred8x8l_down_left_sse2;

            h->pred8x8l [DIAG_DOWN_RIGHT_PRED ] = ff_pred8x8l_down_right_sse2;

            h->pred8x8l [VERT_RIGHT_PRED      ] = ff_pred8x8l_vertical_right_sse2;

            h->pred8x8l [VERT_LEFT_PRED       ] = ff_pred8x8l_vertical_left_sse2;

            h->pred8x8l [HOR_DOWN_PRED        ] = ff_pred8x8l_horizontal_down_sse2;

            if (codec_id == AV_CODEC_ID_VP8) {

                h->pred16x16[PLANE_PRED8x8    ] = ff_pred16x16_tm_vp8_sse2;

                h->pred8x8  [PLANE_PRED8x8    ] = ff_pred8x8_tm_vp8_sse2;

            } else {

                if (chroma_format_idc == 1)

                    h->pred8x8  [PLANE_PRED8x8] = ff_pred8x8_plane_sse2;

                if (codec_id == AV_CODEC_ID_SVQ3) {

                    h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_sse2;

                } else if (codec_id == AV_CODEC_ID_RV40) {

                    h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_rv40_sse2;

                } else {

                    h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_h264_sse2;

                }

            }

        }

        if (mm_flags & AV_CPU_FLAG_SSSE3) {

            h->pred16x16[HOR_PRED8x8          ] = ff_pred16x16_horizontal_ssse3;

            h->pred16x16[DC_PRED8x8           ] = ff_pred16x16_dc_ssse3;

            if (chroma_format_idc == 1)

                h->pred8x8  [HOR_PRED8x8      ] = ff_pred8x8_horizontal_ssse3;

            h->pred8x8l [TOP_DC_PRED          ] = ff_pred8x8l_top_dc_ssse3;

            h->pred8x8l [DC_PRED              ] = ff_pred8x8l_dc_ssse3;

            h->pred8x8l [HOR_PRED             ] = ff_pred8x8l_horizontal_ssse3;

            h->pred8x8l [VERT_PRED            ] = ff_pred8x8l_vertical_ssse3;

            h->pred8x8l [DIAG_DOWN_LEFT_PRED  ] = ff_pred8x8l_down_left_ssse3;

            h->pred8x8l [DIAG_DOWN_RIGHT_PRED ] = ff_pred8x8l_down_right_ssse3;

            h->pred8x8l [VERT_RIGHT_PRED      ] = ff_pred8x8l_vertical_right_ssse3;

            h->pred8x8l [VERT_LEFT_PRED       ] = ff_pred8x8l_vertical_left_ssse3;

            h->pred8x8l [HOR_UP_PRED          ] = ff_pred8x8l_horizontal_up_ssse3;

            h->pred8x8l [HOR_DOWN_PRED        ] = ff_pred8x8l_horizontal_down_ssse3;

            if (codec_id == AV_CODEC_ID_VP8) {

                h->pred8x8  [PLANE_PRED8x8    ] = ff_pred8x8_tm_vp8_ssse3;

                h->pred4x4  [TM_VP8_PRED      ] = ff_pred4x4_tm_vp8_ssse3;

            } else {

                if (chroma_format_idc == 1)

                    h->pred8x8  [PLANE_PRED8x8] = ff_pred8x8_plane_ssse3;

                if (codec_id == AV_CODEC_ID_SVQ3) {

                    h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_ssse3;

                } else if (codec_id == AV_CODEC_ID_RV40) {

                    h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_rv40_ssse3;

                } else {

                    h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_h264_ssse3;

                }

            }

        }

    } else if (bit_depth == 10) {

        if (mm_flags & AV_CPU_FLAG_MMXEXT) {

            h->pred4x4[DC_PRED             ] = ff_pred4x4_dc_10_mmxext;

            h->pred4x4[HOR_UP_PRED         ] = ff_pred4x4_horizontal_up_10_mmxext;

            if (chroma_format_idc == 1)

                h->pred8x8[DC_PRED8x8      ] = ff_pred8x8_dc_10_mmxext;

            h->pred8x8l[DC_128_PRED        ] = ff_pred8x8l_128_dc_10_mmxext;

            h->pred16x16[DC_PRED8x8        ] = ff_pred16x16_dc_10_mmxext;

            h->pred16x16[TOP_DC_PRED8x8    ] = ff_pred16x16_top_dc_10_mmxext;

            h->pred16x16[DC_128_PRED8x8    ] = ff_pred16x16_128_dc_10_mmxext;

            h->pred16x16[LEFT_DC_PRED8x8   ] = ff_pred16x16_left_dc_10_mmxext;

            h->pred16x16[VERT_PRED8x8      ] = ff_pred16x16_vertical_10_mmxext;

            h->pred16x16[HOR_PRED8x8       ] = ff_pred16x16_horizontal_10_mmxext;

        }

        if (mm_flags & AV_CPU_FLAG_SSE2) {

            h->pred4x4[DIAG_DOWN_LEFT_PRED ] = ff_pred4x4_down_left_10_sse2;

            h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_sse2;

            h->pred4x4[VERT_LEFT_PRED      ] = ff_pred4x4_vertical_left_10_sse2;

            h->pred4x4[VERT_RIGHT_PRED     ] = ff_pred4x4_vertical_right_10_sse2;

            h->pred4x4[HOR_DOWN_PRED       ] = ff_pred4x4_horizontal_down_10_sse2;

            if (chroma_format_idc == 1) {

                h->pred8x8[DC_PRED8x8      ] = ff_pred8x8_dc_10_sse2;

                h->pred8x8[TOP_DC_PRED8x8  ] = ff_pred8x8_top_dc_10_sse2;

                h->pred8x8[PLANE_PRED8x8   ] = ff_pred8x8_plane_10_sse2;

                h->pred8x8[VERT_PRED8x8    ] = ff_pred8x8_vertical_10_sse2;

                h->pred8x8[HOR_PRED8x8     ] = ff_pred8x8_horizontal_10_sse2;

            }

            h->pred8x8l[VERT_PRED           ] = ff_pred8x8l_vertical_10_sse2;

            h->pred8x8l[HOR_PRED            ] = ff_pred8x8l_horizontal_10_sse2;

            h->pred8x8l[DC_PRED             ] = ff_pred8x8l_dc_10_sse2;

            h->pred8x8l[DC_128_PRED         ] = ff_pred8x8l_128_dc_10_sse2;

            h->pred8x8l[TOP_DC_PRED         ] = ff_pred8x8l_top_dc_10_sse2;

            h->pred8x8l[DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_10_sse2;

            h->pred8x8l[DIAG_DOWN_RIGHT_PRED] = ff_pred8x8l_down_right_10_sse2;

            h->pred8x8l[VERT_RIGHT_PRED     ] = ff_pred8x8l_vertical_right_10_sse2;

            h->pred8x8l[HOR_UP_PRED         ] = ff_pred8x8l_horizontal_up_10_sse2;

            h->pred16x16[DC_PRED8x8        ] = ff_pred16x16_dc_10_sse2;

            h->pred16x16[TOP_DC_PRED8x8    ] = ff_pred16x16_top_dc_10_sse2;

            h->pred16x16[DC_128_PRED8x8    ] = ff_pred16x16_128_dc_10_sse2;

            h->pred16x16[LEFT_DC_PRED8x8   ] = ff_pred16x16_left_dc_10_sse2;

            h->pred16x16[VERT_PRED8x8      ] = ff_pred16x16_vertical_10_sse2;

            h->pred16x16[HOR_PRED8x8       ] = ff_pred16x16_horizontal_10_sse2;

        }

        if (mm_flags & AV_CPU_FLAG_SSSE3) {

            h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_ssse3;

            h->pred4x4[VERT_RIGHT_PRED     ] = ff_pred4x4_vertical_right_10_ssse3;

            h->pred4x4[HOR_DOWN_PRED       ] = ff_pred4x4_horizontal_down_10_ssse3;

            h->pred8x8l[HOR_PRED            ] = ff_pred8x8l_horizontal_10_ssse3;

            h->pred8x8l[DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_10_ssse3;

            h->pred8x8l[DIAG_DOWN_RIGHT_PRED] = ff_pred8x8l_down_right_10_ssse3;

            h->pred8x8l[VERT_RIGHT_PRED     ] = ff_pred8x8l_vertical_right_10_ssse3;

            h->pred8x8l[HOR_UP_PRED         ] = ff_pred8x8l_horizontal_up_10_ssse3;

        }

#if HAVE_AVX

        if (mm_flags & AV_CPU_FLAG_AVX) {

            h->pred4x4[DIAG_DOWN_LEFT_PRED ] = ff_pred4x4_down_left_10_avx;

            h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_avx;

            h->pred4x4[VERT_LEFT_PRED      ] = ff_pred4x4_vertical_left_10_avx;

            h->pred4x4[VERT_RIGHT_PRED     ] = ff_pred4x4_vertical_right_10_avx;

            h->pred4x4[HOR_DOWN_PRED       ] = ff_pred4x4_horizontal_down_10_avx;

            h->pred8x8l[VERT_PRED           ] = ff_pred8x8l_vertical_10_avx;

            h->pred8x8l[HOR_PRED            ] = ff_pred8x8l_horizontal_10_avx;

            h->pred8x8l[DC_PRED             ] = ff_pred8x8l_dc_10_avx;

            h->pred8x8l[TOP_DC_PRED         ] = ff_pred8x8l_top_dc_10_avx;

            h->pred8x8l[DIAG_DOWN_RIGHT_PRED] = ff_pred8x8l_down_right_10_avx;

            h->pred8x8l[DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_10_avx;

            h->pred8x8l[VERT_RIGHT_PRED     ] = ff_pred8x8l_vertical_right_10_avx;

            h->pred8x8l[HOR_UP_PRED         ] = ff_pred8x8l_horizontal_up_10_avx;

        }

#endif /* HAVE_AVX */

    }

#endif /* HAVE_YASM */

}


static void qobject_input_optional(Visitor *v, const char *name, bool *present)

{

    QObjectInputVisitor *qiv = to_qiv(v);

    QObject *qobj = qobject_input_get_object(qiv, name, false, NULL);

    if (!qobj) {

        *present = false;

        return;

    }

    *present = true;

}


static int coroutine_fn copy_sectors(BlockDriverState *bs,

                                     uint64_t start_sect,

                                     uint64_t cluster_offset,

                                     int n_start, int n_end)

{

    BDRVQcowState *s = bs->opaque;

    QEMUIOVector qiov;

    struct iovec iov;

    int n, ret;

    n = n_end - n_start;

    if (n <= 0) {

        return 0;

    }

    iov.iov_len = n * BDRV_SECTOR_SIZE;

    iov.iov_base = qemu_blockalign(bs, iov.iov_len);

    qemu_iovec_init_external(&qiov, &iov, 1);

    BLKDBG_EVENT(bs->file, BLKDBG_COW_READ);

    if (!bs->drv) {

        return -ENOMEDIUM;

    }

    /* Call .bdrv_co_readv() directly instead of using the public block-layer

     * interface.  This avoids double I/O throttling and request tracking,

     * which can lead to deadlock when block layer copy-on-read is enabled.

     */

    ret = bs->drv->bdrv_co_readv(bs, start_sect + n_start, n, &qiov);

    if (ret < 0) {

        goto out;

    }

    if (s->crypt_method) {

        qcow2_encrypt_sectors(s, start_sect + n_start,

                        iov.iov_base, iov.iov_base, n, 1,

                        &s->aes_encrypt_key);

    }

    ret = qcow2_pre_write_overlap_check(bs, 0,

            cluster_offset + n_start * BDRV_SECTOR_SIZE, n * BDRV_SECTOR_SIZE);

    if (ret < 0) {

        goto out;

    }

    BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);

    ret = bdrv_co_writev(bs->file, (cluster_offset >> 9) + n_start, n, &qiov);

    if (ret < 0) {

        goto out;

    }

    ret = 0;

out:

    qemu_vfree(iov.iov_base);

    return ret;

}


static uint32_t  ahci_port_read(AHCIState *s, int port, int offset)

{

    uint32_t val;

    AHCIPortRegs *pr;

    pr = &s->dev[port].port_regs;

    switch (offset) {

    case PORT_LST_ADDR:

        val = pr->lst_addr;

        break;

    case PORT_LST_ADDR_HI:

        val = pr->lst_addr_hi;

        break;

    case PORT_FIS_ADDR:

        val = pr->fis_addr;

        break;

    case PORT_FIS_ADDR_HI:

        val = pr->fis_addr_hi;

        break;

    case PORT_IRQ_STAT:

        val = pr->irq_stat;

        break;

    case PORT_IRQ_MASK:

        val = pr->irq_mask;

        break;

    case PORT_CMD:

        val = pr->cmd;

        break;

    case PORT_TFDATA:

        val = ((uint16_t)s->dev[port].port.ifs[0].error << 8) |

              s->dev[port].port.ifs[0].status;

        break;

    case PORT_SIG:

        val = pr->sig;

        break;

    case PORT_SCR_STAT:

        if (s->dev[port].port.ifs[0].bs) {

            val = SATA_SCR_SSTATUS_DET_DEV_PRESENT_PHY_UP |

                  SATA_SCR_SSTATUS_SPD_GEN1 | SATA_SCR_SSTATUS_IPM_ACTIVE;

        } else {

            val = SATA_SCR_SSTATUS_DET_NODEV;

        }

        break;

    case PORT_SCR_CTL:

        val = pr->scr_ctl;

        break;

    case PORT_SCR_ERR:

        val = pr->scr_err;

        break;

    case PORT_SCR_ACT:

        pr->scr_act &= ~s->dev[port].finished;

        s->dev[port].finished = 0;

        val = pr->scr_act;

        break;

    case PORT_CMD_ISSUE:

        val = pr->cmd_issue;

        break;

    case PORT_RESERVED:

    default:

        val = 0;

    }

    DPRINTF(port, "offset: 0x%x val: 0x%x\n", offset, val);

    return val;

}


av_cold void ff_wmv2_common_init(Wmv2Context *w)

{

    MpegEncContext *const s = &w->s;

    ff_blockdsp_init(&s->bdsp, s->avctx);

    ff_wmv2dsp_init(&w->wdsp);

    s->idsp.perm_type = w->wdsp.idct_perm;

    ff_init_scantable_permutation(s->idsp.idct_permutation,

                                  w->wdsp.idct_perm);

    ff_init_scantable(s->idsp.idct_permutation, &w->abt_scantable[0],

                      ff_wmv2_scantableA);

    ff_init_scantable(s->idsp.idct_permutation, &w->abt_scantable[1],

                      ff_wmv2_scantableB);

    ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable,

                      ff_wmv1_scantable[1]);

    ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable,

                      ff_wmv1_scantable[2]);

    ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable,

                      ff_wmv1_scantable[3]);

    ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable,

                      ff_wmv1_scantable[0]);

    s->idsp.idct_put = w->wdsp.idct_put;

    s->idsp.idct_add = w->wdsp.idct_add;

    s->idsp.idct     = NULL;

}


static int decode_subpacket(COOKContext *q, uint8_t *inbuffer,

                            int sub_packet_size, int16_t *outbuffer) {

    int i,j;

    int value;

    float* tmp_ptr;

    /* packet dump */

//    for (i=0 ; i<sub_packet_size ; i++) {

//        av_log(NULL, AV_LOG_ERROR, "%02x", inbuffer[i]);

//    }

//    av_log(NULL, AV_LOG_ERROR, "\n");

    decode_bytes(inbuffer, q->decoded_bytes_buffer, sub_packet_size);

    init_get_bits(&q->gb, q->decoded_bytes_buffer, sub_packet_size*8);

    decode_gain_info(&q->gb, &q->gain_current);

    memcpy(&q->gain_copy, &q->gain_current ,sizeof(COOKgain));  //This copy does not seem to be used. FIXME

    if(q->nb_channels==2 && q->joint_stereo==1){

        joint_decode(q, q->decode_buf_ptr[0], q->decode_buf_ptr[2]);

        /* Swap buffer pointers. */

        tmp_ptr = q->decode_buf_ptr[1];

        q->decode_buf_ptr[1] = q->decode_buf_ptr[0];

        q->decode_buf_ptr[0] = tmp_ptr;

        tmp_ptr = q->decode_buf_ptr[3];

        q->decode_buf_ptr[3] = q->decode_buf_ptr[2];

        q->decode_buf_ptr[2] = tmp_ptr;

        /* FIXME: Rethink the gainbuffer handling, maybe a rename?

           now/previous swap */

        q->gain_now_ptr = &q->gain_now;

        q->gain_previous_ptr = &q->gain_previous;

        for (i=0 ; i<q->nb_channels ; i++){

            cook_imlt(q, q->decode_buf_ptr[i*2], q->mono_mdct_output, q->mlt_tmp);

            gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr,

                            q->gain_previous_ptr, q->previous_buffer_ptr[0]);

            /* Swap out the previous buffer. */

            tmp_ptr = q->previous_buffer_ptr[0];

            q->previous_buffer_ptr[0] = q->previous_buffer_ptr[1];

            q->previous_buffer_ptr[1] = tmp_ptr;

            /* Clip and convert the floats to 16 bits. */

            for (j=0 ; j<q->samples_per_frame ; j++){

                value = lrintf(q->mono_mdct_output[j]);

                if(value < -32768) value = -32768;

                else if(value > 32767) value = 32767;

                outbuffer[2*j+i] = value;

            }

        }

        memcpy(&q->gain_now, &q->gain_previous, sizeof(COOKgain));

        memcpy(&q->gain_previous, &q->gain_current, sizeof(COOKgain));

    } else if (q->nb_channels==2 && q->joint_stereo==0) {

            /* channel 0 */

            mono_decode(q, q->decode_buf_ptr[0]);

            tmp_ptr = q->decode_buf_ptr[0];

            q->decode_buf_ptr[0] = q->decode_buf_ptr[1];

            q->decode_buf_ptr[1] = q->decode_buf_ptr[2];

            q->decode_buf_ptr[2] = q->decode_buf_ptr[3];

            q->decode_buf_ptr[3] = tmp_ptr;

            q->gain_now_ptr = &q->gain_now;

            q->gain_previous_ptr = &q->gain_previous;

            cook_imlt(q, q->decode_buf_ptr[0], q->mono_mdct_output,q->mlt_tmp);

            gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr,

                            q->gain_previous_ptr, q->previous_buffer_ptr[0]);

            /* Swap out the previous buffer. */

            tmp_ptr = q->previous_buffer_ptr[0];

            q->previous_buffer_ptr[0] = q->previous_buffer_ptr[1];

            q->previous_buffer_ptr[1] = tmp_ptr;

            for (j=0 ; j<q->samples_per_frame ; j++){

                value = lrintf(q->mono_mdct_output[j]);

                if(value < -32768) value = -32768;

                else if(value > 32767) value = 32767;

                outbuffer[2*j+1] = value;

            }

            /* channel 1 */

            //av_log(NULL,AV_LOG_ERROR,"bits = %d\n",get_bits_count(&q->gb));

            init_get_bits(&q->gb, q->decoded_bytes_buffer, sub_packet_size*8+q->bits_per_subpacket);

            decode_gain_info(&q->gb, &q->gain_current);

            //memcpy(&q->gain_copy, &q->gain_current ,sizeof(COOKgain));

            mono_decode(q, q->decode_buf_ptr[0]);

            tmp_ptr = q->decode_buf_ptr[0];

            q->decode_buf_ptr[1] = q->decode_buf_ptr[2];

            q->decode_buf_ptr[2] = q->decode_buf_ptr[3];

            q->decode_buf_ptr[3] = tmp_ptr;

            q->gain_now_ptr = &q->gain_now;

            q->gain_previous_ptr = &q->gain_previous;

            cook_imlt(q, q->decode_buf_ptr[0], q->mono_mdct_output,q->mlt_tmp);

            gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr, q->gain_previous_ptr, q->previous_buffer_ptr[0]);

            /* Swap out the previous buffer. */

            tmp_ptr = q->previous_buffer_ptr[0];

            q->previous_buffer_ptr[0] = q->previous_buffer_ptr[1];

            q->previous_buffer_ptr[1] = tmp_ptr;

            for (j=0 ; j<q->samples_per_frame ; j++){

                value = lrintf(q->mono_mdct_output[j]);

                if(value < -32768) value = -32768;

                else if(value > 32767) value = 32767;

                outbuffer[2*j] = value;

            }

            /* Swap out the previous buffer. */

            memcpy(&q->gain_now, &q->gain_previous, sizeof(COOKgain));

            memcpy(&q->gain_previous, &q->gain_current, sizeof(COOKgain));

    } else {

        mono_decode(q, q->decode_buf_ptr[0]);

        /* Swap buffer pointers. */

        tmp_ptr = q->decode_buf_ptr[1];

        q->decode_buf_ptr[1] = q->decode_buf_ptr[0];

        q->decode_buf_ptr[0] = tmp_ptr;

        /* FIXME: Rethink the gainbuffer handling, maybe a rename?

           now/previous swap */

        q->gain_now_ptr = &q->gain_now;

        q->gain_previous_ptr = &q->gain_previous;

        cook_imlt(q, q->decode_buf_ptr[0], q->mono_mdct_output,q->mlt_tmp);

        gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr,

                        q->gain_previous_ptr, q->mono_previous_buffer1);

        /* Clip and convert the floats to 16 bits */

        for (j=0 ; j<q->samples_per_frame ; j++){

            value = lrintf(q->mono_mdct_output[j]);

            if(value < -32768) value = -32768;

            else if(value > 32767) value = 32767;

            outbuffer[j] = value;

        }

        memcpy(&q->gain_now, &q->gain_previous, sizeof(COOKgain));

        memcpy(&q->gain_previous, &q->gain_current, sizeof(COOKgain));

    }

    return q->samples_per_frame * sizeof(int16_t);

}


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

                                 ptrdiff_t stride)

{

    copy_width16_msa(src, stride, dst, stride, 16);

}


static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSurface *tmpoutsurf)

{

    NvencContext *ctx = avctx->priv_data;

    NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;

    NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;

    uint32_t slice_mode_data;

    uint32_t *slice_offsets = NULL;

    NV_ENC_LOCK_BITSTREAM lock_params = { 0 };

    NVENCSTATUS nv_status;

    int res = 0;

    enum AVPictureType pict_type;

    switch (avctx->codec->id) {

    case AV_CODEC_ID_H264:

      slice_mode_data = ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;

      break;

    case AV_CODEC_ID_H265:

      slice_mode_data = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;

      break;

    default:

      av_log(avctx, AV_LOG_ERROR, "Unknown codec name\n");

      res = AVERROR(EINVAL);

      goto error;

    }

    slice_offsets = av_mallocz(slice_mode_data * sizeof(*slice_offsets));

    if (!slice_offsets) {

        res = AVERROR(ENOMEM);

        goto error;

    }

    lock_params.version = NV_ENC_LOCK_BITSTREAM_VER;

    lock_params.doNotWait = 0;

    lock_params.outputBitstream = tmpoutsurf->output_surface;

    lock_params.sliceOffsets = slice_offsets;

    nv_status = p_nvenc->nvEncLockBitstream(ctx->nvencoder, &lock_params);

    if (nv_status != NV_ENC_SUCCESS) {

        res = nvenc_print_error(avctx, nv_status, "Failed locking bitstream buffer");

        goto error;

    }

    if (res = ff_alloc_packet2(avctx, pkt, lock_params.bitstreamSizeInBytes,0)) {

        p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface);

        goto error;

    }

    memcpy(pkt->data, lock_params.bitstreamBufferPtr, lock_params.bitstreamSizeInBytes);

    nv_status = p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface);

    if (nv_status != NV_ENC_SUCCESS)

        nvenc_print_error(avctx, nv_status, "Failed unlocking bitstream buffer, expect the gates of mordor to open");

    if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) {

        ctx->registered_frames[tmpoutsurf->reg_idx].mapped -= 1;

        if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped == 0) {

            p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource);

            p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].regptr);

            ctx->registered_frames[tmpoutsurf->reg_idx].regptr = NULL;

        } else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) {

            res = AVERROR_BUG;

            goto error;

        }

        av_frame_unref(tmpoutsurf->in_ref);

        tmpoutsurf->input_surface = NULL;

    }

    switch (lock_params.pictureType) {

    case NV_ENC_PIC_TYPE_IDR:

        pkt->flags |= AV_PKT_FLAG_KEY;

    case NV_ENC_PIC_TYPE_I:

        pict_type = AV_PICTURE_TYPE_I;

        break;

    case NV_ENC_PIC_TYPE_P:

        pict_type = AV_PICTURE_TYPE_P;

        break;

    case NV_ENC_PIC_TYPE_B:

        pict_type = AV_PICTURE_TYPE_B;

        break;

    case NV_ENC_PIC_TYPE_BI:

        pict_type = AV_PICTURE_TYPE_BI;

        break;

    default:

        av_log(avctx, AV_LOG_ERROR, "Unknown picture type encountered, expect the output to be broken.\n");

        av_log(avctx, AV_LOG_ERROR, "Please report this error and include as much information on how to reproduce it as possible.\n");

        res = AVERROR_EXTERNAL;

        goto error;

    }

#if FF_API_CODED_FRAME

FF_DISABLE_DEPRECATION_WARNINGS

    avctx->coded_frame->pict_type = pict_type;

FF_ENABLE_DEPRECATION_WARNINGS

#endif

    ff_side_data_set_encoder_stats(pkt,

        (lock_params.frameAvgQP - 1) * FF_QP2LAMBDA, NULL, 0, pict_type);

    res = nvenc_set_timestamp(avctx, &lock_params, pkt);

    if (res < 0)

        goto error2;

    av_free(slice_offsets);

    return 0;

error:

    timestamp_queue_dequeue(ctx->timestamp_list);

error2:

    av_free(slice_offsets);

    return res;

}


static int img_read_header(AVFormatContext *s1)

{

    VideoDemuxData *s = s1->priv_data;

    int first_index, last_index;

    AVStream *st;

    enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;

    s1->ctx_flags |= AVFMTCTX_NOHEADER;

    st = avformat_new_stream(s1, NULL);

    if (!st) {

        return AVERROR(ENOMEM);

    }

    if (s->pixel_format &&

        (pix_fmt = av_get_pix_fmt(s->pixel_format)) == AV_PIX_FMT_NONE) {

        av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n",

               s->pixel_format);

        return AVERROR(EINVAL);

    }

    av_strlcpy(s->path, s1->filename, sizeof(s->path));

    s->img_number = 0;

    s->img_count  = 0;

    /* find format */

    if (s1->iformat->flags & AVFMT_NOFILE)

        s->is_pipe = 0;

    else {

        s->is_pipe       = 1;

        st->need_parsing = AVSTREAM_PARSE_FULL;

    }

    if (s->ts_from_file)

        avpriv_set_pts_info(st, 60, 1, 1);

    else

        avpriv_set_pts_info(st, 60, s->framerate.den, s->framerate.num);

    if (s->width && s->height) {

        st->codec->width  = s->width;

        st->codec->height = s->height;

    }

    if (!s->is_pipe) {

        if (s->pattern_type == PT_GLOB_SEQUENCE) {

        s->use_glob = is_glob(s->path);

        if (s->use_glob) {

            char *p = s->path, *q, *dup;

            int gerr;

            av_log(s1, AV_LOG_WARNING, "Pattern type 'glob_sequence' is deprecated: "

                   "use pattern_type 'glob' instead\n");

#if HAVE_GLOB

            dup = q = av_strdup(p);

            while (*q) {

                /* Do we have room for the next char and a \ insertion? */

                if ((p - s->path) >= (sizeof(s->path) - 2))

                  break;

                if (*q == '%' && strspn(q + 1, "%*?[]{}"))

                    ++q;

                else if (strspn(q, "\\*?[]{}"))

                    *p++ = '\\';

                *p++ = *q++;

            }

            *p = 0;

            av_free(dup);

            gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate);

            if (gerr != 0) {

                return AVERROR(ENOENT);

            }

            first_index = 0;

            last_index = s->globstate.gl_pathc - 1;

#endif

        }

        }

        if ((s->pattern_type == PT_GLOB_SEQUENCE && !s->use_glob) || s->pattern_type == PT_SEQUENCE) {

            if (find_image_range(&first_index, &last_index, s->path,

                                 s->start_number, s->start_number_range) < 0) {

                av_log(s1, AV_LOG_ERROR,

                       "Could find no file with with path '%s' and index in the range %d-%d\n",

                       s->path, s->start_number, s->start_number + s->start_number_range - 1);

                return AVERROR(ENOENT);

            }

        } else if (s->pattern_type == PT_GLOB) {

#if HAVE_GLOB

            int gerr;

            gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate);

            if (gerr != 0) {

                return AVERROR(ENOENT);

            }

            first_index = 0;

            last_index = s->globstate.gl_pathc - 1;

            s->use_glob = 1;

#else

            av_log(s1, AV_LOG_ERROR,

                   "Pattern type 'glob' was selected but globbing "

                   "is not supported by this libavformat build\n");

            return AVERROR(ENOSYS);

#endif

        } else if (s->pattern_type != PT_GLOB_SEQUENCE) {

            av_log(s1, AV_LOG_ERROR,

                   "Unknown value '%d' for pattern_type option\n", s->pattern_type);

            return AVERROR(EINVAL);

        }

        s->img_first  = first_index;

        s->img_last   = last_index;

        s->img_number = first_index;

        /* compute duration */

        st->start_time = 0;

        st->duration   = last_index - first_index + 1;

    }

    if (s1->video_codec_id) {

        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

        st->codec->codec_id   = s1->video_codec_id;

    } else if (s1->audio_codec_id) {

        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

        st->codec->codec_id   = s1->audio_codec_id;

    } else {

        const char *str = strrchr(s->path, '.');

        s->split_planes       = str && !av_strcasecmp(str + 1, "y");

        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

        st->codec->codec_id   = ff_guess_image2_codec(s->path);

        if (st->codec->codec_id == AV_CODEC_ID_LJPEG)

            st->codec->codec_id = AV_CODEC_ID_MJPEG;

    }

    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&

        pix_fmt != AV_PIX_FMT_NONE)

        st->codec->pix_fmt = pix_fmt;

    return 0;

}


static void rgba32_to_rgb24(AVPicture *dst, AVPicture *src,

                            int width, int height)

{

    const uint8_t *s;

    uint8_t *d;

    int src_wrap, dst_wrap, j, y;

    unsigned int v;

    s = src->data[0];

    src_wrap = src->linesize[0] - width * 4;

    d = dst->data[0];

    dst_wrap = dst->linesize[0] - width * 3;

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

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

            v = *(uint32_t *)s;

            s += 4;

            d[0] = v >> 16;

            d[1] = v >> 8;

            d[2] = v;

            d += 3;

        }

        s += src_wrap;

        d += dst_wrap;

    }

}


int opt_codec_debug(void *optctx, const char *opt, const char *arg)

{

    av_log_set_level(AV_LOG_DEBUG);

    return opt_default(NULL, opt, arg);

}


void mips_r4k_init(MachineState *machine)

{

    ram_addr_t ram_size = machine->ram_size;

    const char *cpu_model = machine->cpu_model;

    const char *kernel_filename = machine->kernel_filename;

    const char *kernel_cmdline = machine->kernel_cmdline;

    const char *initrd_filename = machine->initrd_filename;

    char *filename;

    MemoryRegion *address_space_mem = get_system_memory();

    MemoryRegion *ram = g_new(MemoryRegion, 1);

    MemoryRegion *bios;

    MemoryRegion *iomem = g_new(MemoryRegion, 1);

    MemoryRegion *isa_io = g_new(MemoryRegion, 1);

    MemoryRegion *isa_mem = g_new(MemoryRegion, 1);

    int bios_size;

    MIPSCPU *cpu;

    CPUMIPSState *env;

    ResetData *reset_info;

    int i;

    qemu_irq *i8259;

    ISABus *isa_bus;

    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];

    DriveInfo *dinfo;

    int be;

    /* init CPUs */

    if (cpu_model == NULL) {

#ifdef TARGET_MIPS64

        cpu_model = "R4000";

#else

        cpu_model = "24Kf";

#endif

    }

    cpu = cpu_mips_init(cpu_model);

    if (cpu == NULL) {

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

        exit(1);

    }

    env = &cpu->env;

    reset_info = g_malloc0(sizeof(ResetData));

    reset_info->cpu = cpu;

    reset_info->vector = env->active_tc.PC;

    qemu_register_reset(main_cpu_reset, reset_info);

    /* allocate RAM */

    if (ram_size > (256 << 20)) {

        fprintf(stderr,

                "qemu: Too much memory for this machine: %d MB, maximum 256 MB\n",

                ((unsigned int)ram_size / (1 << 20)));

        exit(1);

    }

    memory_region_allocate_system_memory(ram, NULL, "mips_r4k.ram", ram_size);

    memory_region_add_subregion(address_space_mem, 0, ram);

    memory_region_init_io(iomem, NULL, &mips_qemu_ops, NULL, "mips-qemu", 0x10000);

    memory_region_add_subregion(address_space_mem, 0x1fbf0000, iomem);

    /* Try to load a BIOS image. If this fails, we continue regardless,

       but initialize the hardware ourselves. When a kernel gets

       preloaded we also initialize the hardware, since the BIOS wasn't

       run. */

    if (bios_name == NULL)

        bios_name = BIOS_FILENAME;

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

    if (filename) {

        bios_size = get_image_size(filename);

    } else {

        bios_size = -1;

    }

#ifdef TARGET_WORDS_BIGENDIAN

    be = 1;

#else

    be = 0;

#endif

    if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) {

        bios = g_new(MemoryRegion, 1);

        memory_region_init_ram(bios, NULL, "mips_r4k.bios", BIOS_SIZE,

                               &error_abort);

        vmstate_register_ram_global(bios);

        memory_region_set_readonly(bios, true);

        memory_region_add_subregion(get_system_memory(), 0x1fc00000, bios);

        load_image_targphys(filename, 0x1fc00000, BIOS_SIZE);

    } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {

        uint32_t mips_rom = 0x00400000;

        if (!pflash_cfi01_register(0x1fc00000, NULL, "mips_r4k.bios", mips_rom,

                                   blk_by_legacy_dinfo(dinfo),

                                   sector_len, mips_rom / sector_len,

                                   4, 0, 0, 0, 0, be)) {

            fprintf(stderr, "qemu: Error registering flash memory.\n");

	}

    } else if (!qtest_enabled()) {

	/* not fatal */

        fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",

		bios_name);

    }

    g_free(filename);

    if (kernel_filename) {

        loaderparams.ram_size = ram_size;

        loaderparams.kernel_filename = kernel_filename;

        loaderparams.kernel_cmdline = kernel_cmdline;

        loaderparams.initrd_filename = initrd_filename;

        reset_info->vector = load_kernel();

    }

    /* Init CPU internal devices */

    cpu_mips_irq_init_cpu(env);

    cpu_mips_clock_init(env);

    /* ISA bus: IO space at 0x14000000, mem space at 0x10000000 */

    memory_region_init_alias(isa_io, NULL, "isa-io",

                             get_system_io(), 0, 0x00010000);

    memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000);

    memory_region_add_subregion(get_system_memory(), 0x14000000, isa_io);

    memory_region_add_subregion(get_system_memory(), 0x10000000, isa_mem);

    isa_bus = isa_bus_new(NULL, isa_mem, get_system_io());

    /* The PIC is attached to the MIPS CPU INT0 pin */

    i8259 = i8259_init(isa_bus, env->irq[2]);

    isa_bus_irqs(isa_bus, i8259);

    rtc_init(isa_bus, 2000, NULL);

    pit = pit_init(isa_bus, 0x40, 0, NULL);

    serial_hds_isa_init(isa_bus, MAX_SERIAL_PORTS);

    isa_vga_init(isa_bus);

    if (nd_table[0].used)

        isa_ne2000_init(isa_bus, 0x300, 9, &nd_table[0]);

    ide_drive_get(hd, ARRAY_SIZE(hd));

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

        isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i],

                     hd[MAX_IDE_DEVS * i],

		     hd[MAX_IDE_DEVS * i + 1]);

    isa_create_simple(isa_bus, "i8042");

}


static int get_packetheader(NUTContext *nut, ByteIOContext *bc, int calculate_checksum)

{

    int64_t start, size;

//    start= url_ftell(bc) - 8;

    size= get_v(bc);

    init_checksum(bc, calculate_checksum ? av_crc04C11DB7_update : NULL, 1);

//    nut->packet_start[2] = start;

//    nut->written_packet_size= size;

    return size;

}


static int decode_slice(AVCodecContext *avctx, void *tdata)

{

    ProresThreadData *td = tdata;

    ProresContext *ctx = avctx->priv_data;

    int mb_x_pos  = td->x_pos;

    int mb_y_pos  = td->y_pos;

    int pic_num   = ctx->pic_num;

    int slice_num = td->slice_num;

    int mbs_per_slice = td->slice_width;

    const uint8_t *buf;

    uint8_t *y_data, *u_data, *v_data, *a_data;

    AVFrame *pic = ctx->frame;

    int i, sf, slice_width_factor;

    int slice_data_size, hdr_size;

    int y_data_size, u_data_size, v_data_size, a_data_size;

    int y_linesize, u_linesize, v_linesize, a_linesize;

    int coff[4];

    int ret;

    buf             = ctx->slice_data[slice_num].index;

    slice_data_size = ctx->slice_data[slice_num + 1].index - buf;

    slice_width_factor = av_log2(mbs_per_slice);

    y_data     = pic->data[0];

    u_data     = pic->data[1];

    v_data     = pic->data[2];

    a_data     = pic->data[3];

    y_linesize = pic->linesize[0];

    u_linesize = pic->linesize[1];

    v_linesize = pic->linesize[2];

    a_linesize = pic->linesize[3];

    if (pic->interlaced_frame) {

        if (!(pic_num ^ pic->top_field_first)) {

            y_data += y_linesize;

            u_data += u_linesize;

            v_data += v_linesize;

            if (a_data)

                a_data += a_linesize;

        }

        y_linesize <<= 1;

        u_linesize <<= 1;

        v_linesize <<= 1;

        a_linesize <<= 1;

    }

    y_data += (mb_y_pos << 4) * y_linesize + (mb_x_pos << 5);

    u_data += (mb_y_pos << 4) * u_linesize + (mb_x_pos << ctx->mb_chroma_factor);

    v_data += (mb_y_pos << 4) * v_linesize + (mb_x_pos << ctx->mb_chroma_factor);

    if (a_data)

        a_data += (mb_y_pos << 4) * a_linesize + (mb_x_pos << 5);

    if (slice_data_size < 6) {

        av_log(avctx, AV_LOG_ERROR, "slice data too small\n");

        return AVERROR_INVALIDDATA;

    }

    /* parse slice header */

    hdr_size    = buf[0] >> 3;

    coff[0]     = hdr_size;

    y_data_size = AV_RB16(buf + 2);

    coff[1]     = coff[0] + y_data_size;

    u_data_size = AV_RB16(buf + 4);

    coff[2]     = coff[1] + u_data_size;

    v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) : slice_data_size - coff[2];

    coff[3]     = coff[2] + v_data_size;

    a_data_size = ctx->alpha_info ? slice_data_size - coff[3] : 0;

    /* if V or alpha component size is negative that means that previous

       component sizes are too large */

    if (v_data_size < 0 || a_data_size < 0 || hdr_size < 6) {

        av_log(avctx, AV_LOG_ERROR, "invalid data size\n");

        return AVERROR_INVALIDDATA;

    }

    sf = av_clip(buf[1], 1, 224);

    sf = sf > 128 ? (sf - 96) << 2 : sf;

    /* scale quantization matrixes according with slice's scale factor */

    /* TODO: this can be SIMD-optimized a lot */

    if (ctx->qmat_changed || sf != td->prev_slice_sf) {

        td->prev_slice_sf = sf;

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

            td->qmat_luma_scaled[ctx->dsp.idct_permutation[i]]   = ctx->qmat_luma[i]   * sf;

            td->qmat_chroma_scaled[ctx->dsp.idct_permutation[i]] = ctx->qmat_chroma[i] * sf;

        }

    }

    /* decode luma plane */

    ret = decode_slice_plane(ctx, td, buf + coff[0], y_data_size,

                             (uint16_t*) y_data, y_linesize,

                             mbs_per_slice, 4, slice_width_factor + 2,

                             td->qmat_luma_scaled, 0);

    if (ret < 0)

        return ret;

    /* decode U chroma plane */

    ret = decode_slice_plane(ctx, td, buf + coff[1], u_data_size,

                             (uint16_t*) u_data, u_linesize,

                             mbs_per_slice, ctx->num_chroma_blocks,

                             slice_width_factor + ctx->chroma_factor - 1,

                             td->qmat_chroma_scaled, 1);

    if (ret < 0)

        return ret;

    /* decode V chroma plane */

    ret = decode_slice_plane(ctx, td, buf + coff[2], v_data_size,

                             (uint16_t*) v_data, v_linesize,

                             mbs_per_slice, ctx->num_chroma_blocks,

                             slice_width_factor + ctx->chroma_factor - 1,

                             td->qmat_chroma_scaled, 1);

    if (ret < 0)

        return ret;

    /* decode alpha plane if available */

    if (a_data && a_data_size)

        decode_alpha_plane(ctx, td, buf + coff[3], a_data_size,

                           (uint16_t*) a_data, a_linesize,

                           mbs_per_slice);

    return 0;

}


static int put_v(ByteIOContext *bc, uint64_t val)

{

    int i;

//    if (bytes_left(s)*8 < 9)

//	return -1;

    if (bytes_left(bc) < 1)

	return -1;

    val &= 0x7FFFFFFFFFFFFFFFULL; // FIXME can only encode upto 63 bits currently

    i= get_length(val);

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

	put_byte(bc, 0x80 | (val>>i));

    }

    put_byte(bc, val&0x7f);

    return 0;

}


static inline void gen_bcond(DisasContext *ctx, int type)

{

    uint32_t bo = BO(ctx->opcode);

    int l1;

    TCGv target;

    ctx->exception = POWERPC_EXCP_BRANCH;

    if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {

        target = tcg_temp_local_new();

        if (type == BCOND_CTR)

            tcg_gen_mov_tl(target, cpu_ctr);

        else if (type == BCOND_TAR)

            gen_load_spr(target, SPR_TAR);

        else

            tcg_gen_mov_tl(target, cpu_lr);

    } else {

        TCGV_UNUSED(target);

    }

    if (LK(ctx->opcode))

        gen_setlr(ctx, ctx->nip);

    l1 = gen_new_label();

    if ((bo & 0x4) == 0) {

        /* Decrement and test CTR */

        TCGv temp = tcg_temp_new();

        if (unlikely(type == BCOND_CTR)) {

            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);

            return;

        }

        tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);

        if (NARROW_MODE(ctx)) {

            tcg_gen_ext32u_tl(temp, cpu_ctr);

        } else {

            tcg_gen_mov_tl(temp, cpu_ctr);

        }

        if (bo & 0x2) {

            tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);

        } else {

            tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);

        }

        tcg_temp_free(temp);

    }

    if ((bo & 0x10) == 0) {

        /* Test CR */

        uint32_t bi = BI(ctx->opcode);

        uint32_t mask = 1 << (3 - (bi & 0x03));

        TCGv_i32 temp = tcg_temp_new_i32();

        if (bo & 0x8) {

            tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);

            tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);

        } else {

            tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);

            tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);

        }

        tcg_temp_free_i32(temp);

    }

    gen_update_cfar(ctx, ctx->nip);

    if (type == BCOND_IM) {

        target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));

        if (likely(AA(ctx->opcode) == 0)) {

            gen_goto_tb(ctx, 0, ctx->nip + li - 4);

        } else {

            gen_goto_tb(ctx, 0, li);

        }

        gen_set_label(l1);

        gen_goto_tb(ctx, 1, ctx->nip);

    } else {

        if (NARROW_MODE(ctx)) {

            tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);

        } else {

            tcg_gen_andi_tl(cpu_nip, target, ~3);

        }

        tcg_gen_exit_tb(0);

        gen_set_label(l1);

        gen_update_nip(ctx, ctx->nip);

        tcg_gen_exit_tb(0);

    }

    if (type == BCOND_LR || type == BCOND_CTR) {

        tcg_temp_free(target);

    }

}


void arm_handle_psci_call(ARMCPU *cpu)

{

    /*

     * This function partially implements the logic for dispatching Power State

     * Coordination Interface (PSCI) calls (as described in ARM DEN 0022B.b),

     * to the extent required for bringing up and taking down secondary cores,

     * and for handling reset and poweroff requests.

     * Additional information about the calling convention used is available in

     * the document 'SMC Calling Convention' (ARM DEN 0028)

     */

    CPUARMState *env = &cpu->env;

    uint64_t param[4];

    uint64_t context_id, mpidr;

    target_ulong entry;

    int32_t ret = 0;

    int i;

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

        /*

         * All PSCI functions take explicit 32-bit or native int sized

         * arguments so we can simply zero-extend all arguments regardless

         * of which exact function we are about to call.

         */

        param[i] = is_a64(env) ? env->xregs[i] : env->regs[i];

    }

    if ((param[0] & QEMU_PSCI_0_2_64BIT) && !is_a64(env)) {

        ret = QEMU_PSCI_RET_INVALID_PARAMS;

        goto err;

    }

    switch (param[0]) {

        CPUState *target_cpu_state;

        ARMCPU *target_cpu;

    case QEMU_PSCI_0_2_FN_PSCI_VERSION:

        ret = QEMU_PSCI_0_2_RET_VERSION_0_2;

        break;

    case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:

        ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */

        break;

    case QEMU_PSCI_0_2_FN_AFFINITY_INFO:

    case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:

        mpidr = param[1];

        switch (param[2]) {

        case 0:

            target_cpu_state = arm_get_cpu_by_id(mpidr);

            if (!target_cpu_state) {

                ret = QEMU_PSCI_RET_INVALID_PARAMS;

                break;

            }

            target_cpu = ARM_CPU(target_cpu_state);

            ret = target_cpu->powered_off ? 1 : 0;

            break;

        default:

            /* Everything above affinity level 0 is always on. */

            ret = 0;

        }

        break;

    case QEMU_PSCI_0_2_FN_SYSTEM_RESET:

        qemu_system_reset_request();

        /* QEMU reset and shutdown are async requests, but PSCI

         * mandates that we never return from the reset/shutdown

         * call, so power the CPU off now so it doesn't execute

         * anything further.

         */

        goto cpu_off;

    case QEMU_PSCI_0_2_FN_SYSTEM_OFF:

        qemu_system_shutdown_request();

        goto cpu_off;

    case QEMU_PSCI_0_1_FN_CPU_ON:

    case QEMU_PSCI_0_2_FN_CPU_ON:

    case QEMU_PSCI_0_2_FN64_CPU_ON:

    {

        /* The PSCI spec mandates that newly brought up CPUs start

         * in the highest exception level which exists and is enabled

         * on the calling CPU. Since the QEMU PSCI implementation is

         * acting as a "fake EL3" or "fake EL2" firmware, this for us

         * means that we want to start at the highest NS exception level

         * that we are providing to the guest.

         * The execution mode should be that which is currently in use

         * by the same exception level on the calling CPU.

         * The CPU should be started with the context_id value

         * in x0 (if AArch64) or r0 (if AArch32).

         */

        int target_el = arm_feature(env, ARM_FEATURE_EL2) ? 2 : 1;

        bool target_aarch64 = arm_el_is_aa64(env, target_el);

        mpidr = param[1];

        entry = param[2];

        context_id = param[3];

        ret = arm_set_cpu_on(mpidr, entry, context_id,

                             target_el, target_aarch64);

        break;

    }

    case QEMU_PSCI_0_1_FN_CPU_OFF:

    case QEMU_PSCI_0_2_FN_CPU_OFF:

        goto cpu_off;

    case QEMU_PSCI_0_1_FN_CPU_SUSPEND:

    case QEMU_PSCI_0_2_FN_CPU_SUSPEND:

    case QEMU_PSCI_0_2_FN64_CPU_SUSPEND:

        /* Affinity levels are not supported in QEMU */

        if (param[1] & 0xfffe0000) {

            ret = QEMU_PSCI_RET_INVALID_PARAMS;

            break;

        }

        /* Powerdown is not supported, we always go into WFI */

        if (is_a64(env)) {

            env->xregs[0] = 0;

        } else {

            env->regs[0] = 0;

        }

        helper_wfi(env);

        break;

    case QEMU_PSCI_0_1_FN_MIGRATE:

    case QEMU_PSCI_0_2_FN_MIGRATE:

        ret = QEMU_PSCI_RET_NOT_SUPPORTED;

        break;

    default:

        g_assert_not_reached();

    }

err:

    if (is_a64(env)) {

        env->xregs[0] = ret;

    } else {

        env->regs[0] = ret;

    }

    return;

cpu_off:

    ret = arm_set_cpu_off(cpu->mp_affinity);

    /* notreached */

    /* sanity check in case something failed */

    assert(ret == QEMU_ARM_POWERCTL_RET_SUCCESS);

}


static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)

{

    int rd;

    uint32_t offset;

    TCGv tmp;

    rd = (insn >> 16) & 0xf;

    tmp = load_reg(s, rd);

    offset = (insn & 0xff) << ((insn >> 7) & 2);

    if (insn & (1 << 24)) {

        /* Pre indexed */

        if (insn & (1 << 23))

            tcg_gen_addi_i32(tmp, tmp, offset);

        else

            tcg_gen_addi_i32(tmp, tmp, -offset);

        tcg_gen_mov_i32(dest, tmp);

        if (insn & (1 << 21))

            store_reg(s, rd, tmp);

        else

            dead_tmp(tmp);

    } else if (insn & (1 << 21)) {

        /* Post indexed */

        tcg_gen_mov_i32(dest, tmp);

        if (insn & (1 << 23))

            tcg_gen_addi_i32(tmp, tmp, offset);

        else

            tcg_gen_addi_i32(tmp, tmp, -offset);

        store_reg(s, rd, tmp);

    } else if (!(insn & (1 << 23)))

        return 1;

    return 0;

}


static MOVFragmentStreamInfo * get_current_frag_stream_info(
    MOVFragmentIndex *frag_index)
{
    MOVFragmentIndexItem * item = &frag_index->item[frag_index->current];
    if (item->current >= 0 && item->current < item->nb_stream_info)
        return &item->stream_info[item->current];
    // This shouldn't happen
}


static void v9fs_wstat(void *opaque)

{

    int32_t fid;

    int err = 0;

    int16_t unused;

    V9fsStat v9stat;

    size_t offset = 7;

    struct stat stbuf;

    V9fsFidState *fidp;

    V9fsPDU *pdu = opaque;

    V9fsState *s = pdu->s;

    pdu_unmarshal(pdu, offset, "dwS", &fid, &unused, &v9stat);

    fidp = get_fid(pdu, fid);

    if (fidp == NULL) {

        err = -EINVAL;

        goto out_nofid;

    }

    /* do we need to sync the file? */

    if (donttouch_stat(&v9stat)) {

        err = v9fs_co_fsync(pdu, fidp, 0);

        goto out;

    }

    if (v9stat.mode != -1) {

        uint32_t v9_mode;

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

        if (err < 0) {

            goto out;

        }

        v9_mode = stat_to_v9mode(&stbuf);

        if ((v9stat.mode & P9_STAT_MODE_TYPE_BITS) !=

            (v9_mode & P9_STAT_MODE_TYPE_BITS)) {

            /* Attempting to change the type */

            err = -EIO;

            goto out;

        }

        err = v9fs_co_chmod(pdu, &fidp->path,

                            v9mode_to_mode(v9stat.mode,

                                           &v9stat.extension));

        if (err < 0) {

            goto out;

        }

    }

    if (v9stat.mtime != -1 || v9stat.atime != -1) {

        struct timespec times[2];

        if (v9stat.atime != -1) {

            times[0].tv_sec = v9stat.atime;

            times[0].tv_nsec = 0;

        } else {

            times[0].tv_nsec = UTIME_OMIT;

        }

        if (v9stat.mtime != -1) {

            times[1].tv_sec = v9stat.mtime;

            times[1].tv_nsec = 0;

        } else {

            times[1].tv_nsec = UTIME_OMIT;

        }

        err = v9fs_co_utimensat(pdu, &fidp->path, times);

        if (err < 0) {

            goto out;

        }

    }

    if (v9stat.n_gid != -1 || v9stat.n_uid != -1) {

        err = v9fs_co_chown(pdu, &fidp->path, v9stat.n_uid, v9stat.n_gid);

        if (err < 0) {

            goto out;

        }

    }

    if (v9stat.name.size != 0) {

        err = v9fs_complete_rename(pdu, fidp, -1, &v9stat.name);

        if (err < 0) {

            goto out;

        }

    }

    if (v9stat.length != -1) {

        err = v9fs_co_truncate(pdu, &fidp->path, v9stat.length);

        if (err < 0) {

            goto out;

        }

    }

    err = offset;

out:

    put_fid(pdu, fidp);

out_nofid:

    v9fs_stat_free(&v9stat);

    complete_pdu(s, pdu, err);

}


static void vnc_colordepth(VncState *vs)

{

    if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {

        /* Sending a WMVi message to notify the client*/

        vnc_lock_output(vs);

        vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);

        vnc_write_u8(vs, 0);

        vnc_write_u16(vs, 1); /* number of rects */

        vnc_framebuffer_update(vs, 0, 0,

                               surface_width(vs->vd->ds),

                               surface_height(vs->vd->ds),

                               VNC_ENCODING_WMVi);

        pixel_format_message(vs);

        vnc_unlock_output(vs);

        vnc_flush(vs);

    } else {

        set_pixel_conversion(vs);

    }

}


static void output_audio_block(AC3EncodeContext *s, int blk)

{

    int ch, i, baie, bnd, got_cpl, ch0;

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

    /* block switching */

    if (!s->eac3) {

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

            put_bits(&s->pb, 1, 0);

    }

    /* dither flags */

    if (!s->eac3) {

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

            put_bits(&s->pb, 1, 1);

    }

    /* dynamic range codes */

    put_bits(&s->pb, 1, 0);

    /* spectral extension */

    if (s->eac3)

        put_bits(&s->pb, 1, 0);

    /* channel coupling */

    if (!s->eac3)

        put_bits(&s->pb, 1, block->new_cpl_strategy);

    if (block->new_cpl_strategy) {

        if (!s->eac3)

            put_bits(&s->pb, 1, block->cpl_in_use);

        if (block->cpl_in_use) {

            int start_sub, end_sub;

            if (s->eac3)

                put_bits(&s->pb, 1, 0); /* enhanced coupling */

            if (!s->eac3 || s->channel_mode != AC3_CHMODE_STEREO) {

                for (ch = 1; ch <= s->fbw_channels; ch++)

                    put_bits(&s->pb, 1, block->channel_in_cpl[ch]);

            }

            if (s->channel_mode == AC3_CHMODE_STEREO)

                put_bits(&s->pb, 1, 0); /* phase flags in use */

            start_sub = (s->start_freq[CPL_CH] - 37) / 12;

            end_sub   = (s->cpl_end_freq       - 37) / 12;

            put_bits(&s->pb, 4, start_sub);

            put_bits(&s->pb, 4, end_sub - 3);

            /* coupling band structure */

            if (s->eac3) {

                put_bits(&s->pb, 1, 0); /* use default */

            } else {

                for (bnd = start_sub+1; bnd < end_sub; bnd++)

                    put_bits(&s->pb, 1, ff_eac3_default_cpl_band_struct[bnd]);

            }

        }

    }

    /* coupling coordinates */

    if (block->cpl_in_use) {

        for (ch = 1; ch <= s->fbw_channels; ch++) {

            if (block->channel_in_cpl[ch]) {

                if (!s->eac3 || block->new_cpl_coords[ch] != 2)

                    put_bits(&s->pb, 1, block->new_cpl_coords[ch]);

                if (block->new_cpl_coords[ch]) {

                    put_bits(&s->pb, 2, block->cpl_master_exp[ch]);

                    for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {

                        put_bits(&s->pb, 4, block->cpl_coord_exp [ch][bnd]);

                        put_bits(&s->pb, 4, block->cpl_coord_mant[ch][bnd]);

                    }

                }

            }

        }

    }

    /* stereo rematrixing */

    if (s->channel_mode == AC3_CHMODE_STEREO) {

        if (!s->eac3 || blk > 0)

            put_bits(&s->pb, 1, block->new_rematrixing_strategy);

        if (block->new_rematrixing_strategy) {

            /* rematrixing flags */

            for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++)

                put_bits(&s->pb, 1, block->rematrixing_flags[bnd]);

        }

    }

    /* exponent strategy */

    if (!s->eac3) {

        for (ch = !block->cpl_in_use; ch <= s->fbw_channels; ch++)

            put_bits(&s->pb, 2, s->exp_strategy[ch][blk]);

        if (s->lfe_on)

            put_bits(&s->pb, 1, s->exp_strategy[s->lfe_channel][blk]);

    }

    /* bandwidth */

    for (ch = 1; ch <= s->fbw_channels; ch++) {

        if (s->exp_strategy[ch][blk] != EXP_REUSE && !block->channel_in_cpl[ch])

            put_bits(&s->pb, 6, s->bandwidth_code);

    }

    /* exponents */

    for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {

        int nb_groups;

        int cpl = (ch == CPL_CH);

        if (s->exp_strategy[ch][blk] == EXP_REUSE)

            continue;

        /* DC exponent */

        put_bits(&s->pb, 4, block->grouped_exp[ch][0] >> cpl);

        /* exponent groups */

        nb_groups = exponent_group_tab[cpl][s->exp_strategy[ch][blk]-1][block->end_freq[ch]-s->start_freq[ch]];

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

            put_bits(&s->pb, 7, block->grouped_exp[ch][i]);

        /* gain range info */

        if (ch != s->lfe_channel && !cpl)

            put_bits(&s->pb, 2, 0);

    }

    /* bit allocation info */

    if (!s->eac3) {

        baie = (blk == 0);

        put_bits(&s->pb, 1, baie);

        if (baie) {

            put_bits(&s->pb, 2, s->slow_decay_code);

            put_bits(&s->pb, 2, s->fast_decay_code);

            put_bits(&s->pb, 2, s->slow_gain_code);

            put_bits(&s->pb, 2, s->db_per_bit_code);

            put_bits(&s->pb, 3, s->floor_code);

        }

    }

    /* snr offset */

    if (!s->eac3) {

        put_bits(&s->pb, 1, block->new_snr_offsets);

        if (block->new_snr_offsets) {

            put_bits(&s->pb, 6, s->coarse_snr_offset);

            for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {

                put_bits(&s->pb, 4, s->fine_snr_offset[ch]);

                put_bits(&s->pb, 3, s->fast_gain_code[ch]);

            }

        }

    } else {

        put_bits(&s->pb, 1, 0); /* no converter snr offset */

    }

    /* coupling leak */

    if (block->cpl_in_use) {

        if (!s->eac3 || block->new_cpl_leak != 2)

            put_bits(&s->pb, 1, block->new_cpl_leak);

        if (block->new_cpl_leak) {

            put_bits(&s->pb, 3, s->bit_alloc.cpl_fast_leak);

            put_bits(&s->pb, 3, s->bit_alloc.cpl_slow_leak);

        }

    }

    if (!s->eac3) {

        put_bits(&s->pb, 1, 0); /* no delta bit allocation */

        put_bits(&s->pb, 1, 0); /* no data to skip */

    }

    /* mantissas */

    got_cpl = !block->cpl_in_use;

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

        int b, q;

        if (!got_cpl && ch > 1 && block->channel_in_cpl[ch-1]) {

            ch0     = ch - 1;

            ch      = CPL_CH;

            got_cpl = 1;

        }

        for (i = s->start_freq[ch]; i < block->end_freq[ch]; i++) {

            q = block->qmant[ch][i];

            b = s->ref_bap[ch][blk][i];

            switch (b) {

            case 0:                                          break;

            case 1: if (q != 128) put_bits (&s->pb,   5, q); break;

            case 2: if (q != 128) put_bits (&s->pb,   7, q); break;

            case 3:               put_sbits(&s->pb,   3, q); break;

            case 4: if (q != 128) put_bits (&s->pb,   7, q); break;

            case 14:              put_sbits(&s->pb,  14, q); break;

            case 15:              put_sbits(&s->pb,  16, q); break;

            default:              put_sbits(&s->pb, b-1, q); break;

            }

        }

        if (ch == CPL_CH)

            ch = ch0;

    }

}


void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,

                                  VirtIOBlockDataPlane **dataplane,

                                  Error **errp)

{

    VirtIOBlockDataPlane *s;

    Error *local_err = NULL;

    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));

    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);

    *dataplane = NULL;

    if (!conf->data_plane && !conf->iothread) {

        return;

    }

    /* Don't try if transport does not support notifiers. */

    if (!k->set_guest_notifiers || !k->set_host_notifier) {

        error_setg(errp,

                   "device is incompatible with x-data-plane "

                   "(transport does not support notifiers)");

        return;

    }

    /* If dataplane is (re-)enabled while the guest is running there could be

     * block jobs that can conflict.

     */

    if (blk_op_is_blocked(conf->conf.blk, BLOCK_OP_TYPE_DATAPLANE,

                          &local_err)) {

        error_setg(errp, "cannot start dataplane thread: %s",

                   error_get_pretty(local_err));

        error_free(local_err);

        return;

    }

    s = g_new0(VirtIOBlockDataPlane, 1);

    s->vdev = vdev;

    s->conf = conf;

    if (conf->iothread) {

        s->iothread = conf->iothread;

        object_ref(OBJECT(s->iothread));

    } else {

        /* Create per-device IOThread if none specified.  This is for

         * x-data-plane option compatibility.  If x-data-plane is removed we

         * can drop this.

         */

        object_initialize(&s->internal_iothread_obj,

                          sizeof(s->internal_iothread_obj),

                          TYPE_IOTHREAD);

        user_creatable_complete(OBJECT(&s->internal_iothread_obj), &error_abort);

        s->iothread = &s->internal_iothread_obj;

    }

    s->ctx = iothread_get_aio_context(s->iothread);

    s->bh = aio_bh_new(s->ctx, notify_guest_bh, s);

    error_setg(&s->blocker, "block device is in use by data plane");

    blk_op_block_all(conf->conf.blk, s->blocker);

    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_RESIZE, s->blocker);

    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker);

    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_BACKUP_SOURCE, s->blocker);

    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_COMMIT, s->blocker);

    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_MIRROR, s->blocker);

    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_STREAM, s->blocker);

    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_REPLACE, s->blocker);

    *dataplane = s;

}


static inline int parse_nal_units(AVCodecParserContext *s, AVCodecContext *avctx,

                      const uint8_t *buf, int buf_size)

{

    HEVCContext   *h  = &((HEVCParseContext *)s->priv_data)->h;

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

    SliceHeader   *sh = &h->sh;

    const uint8_t *buf_end = buf + buf_size;

    int state = -1, i;

    HEVCNAL *nal;

    /* set some sane default values */

    s->pict_type         = AV_PICTURE_TYPE_I;

    s->key_frame         = 0;

    s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;

    h->avctx = avctx;

    if (!buf_size)

        return 0;

    if (h->nals_allocated < 1) {

        HEVCNAL *tmp = av_realloc_array(h->nals, 1, sizeof(*tmp));

        if (!tmp)

            return AVERROR(ENOMEM);

        h->nals = tmp;

        memset(h->nals, 0, sizeof(*tmp));

        h->nals_allocated = 1;

    }

    nal = &h->nals[0];

    for (;;) {

        int src_length, consumed;

        buf = avpriv_find_start_code(buf, buf_end, &state);

        if (--buf + 2 >= buf_end)

            break;

        src_length = buf_end - buf;

        h->nal_unit_type = (*buf >> 1) & 0x3f;

        h->temporal_id   = (*(buf + 1) & 0x07) - 1;

        if (h->nal_unit_type <= NAL_CRA_NUT) {

            // Do not walk the whole buffer just to decode slice segment header

            if (src_length > 20)

                src_length = 20;

        }

        consumed = ff_hevc_extract_rbsp(h, buf, src_length, nal);

        if (consumed < 0)

            return consumed;

        init_get_bits8(gb, nal->data + 2, nal->size);

        switch (h->nal_unit_type) {

        case NAL_VPS:

            ff_hevc_decode_nal_vps(h);

            break;

        case NAL_SPS:

            ff_hevc_decode_nal_sps(h);

            break;

        case NAL_PPS:

            ff_hevc_decode_nal_pps(h);

            break;

        case NAL_SEI_PREFIX:

        case NAL_SEI_SUFFIX:

            ff_hevc_decode_nal_sei(h);

            break;

        case NAL_TRAIL_N:

        case NAL_TRAIL_R:

        case NAL_TSA_N:

        case NAL_TSA_R:

        case NAL_STSA_N:

        case NAL_STSA_R:

        case NAL_RADL_N:

        case NAL_RADL_R:

        case NAL_RASL_N:

        case NAL_RASL_R:

        case NAL_BLA_W_LP:

        case NAL_BLA_W_RADL:

        case NAL_BLA_N_LP:

        case NAL_IDR_W_RADL:

        case NAL_IDR_N_LP:

        case NAL_CRA_NUT:

            sh->first_slice_in_pic_flag = get_bits1(gb);

            s->picture_structure = h->picture_struct;

            s->field_order = h->picture_struct;

            if (IS_IRAP(h)) {

                s->key_frame = 1;

                sh->no_output_of_prior_pics_flag = get_bits1(gb);

            }

            sh->pps_id = get_ue_golomb(gb);

            if (sh->pps_id >= MAX_PPS_COUNT || !h->pps_list[sh->pps_id]) {

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

                return AVERROR_INVALIDDATA;

            }

            h->pps = (HEVCPPS*)h->pps_list[sh->pps_id]->data;

            if (h->pps->sps_id >= MAX_SPS_COUNT || !h->sps_list[h->pps->sps_id]) {

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

                return AVERROR_INVALIDDATA;

            }

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

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

                h->vps = (HEVCVPS*)h->vps_list[h->sps->vps_id]->data;

            }

            if (!sh->first_slice_in_pic_flag) {

                int slice_address_length;

                if (h->pps->dependent_slice_segments_enabled_flag)

                    sh->dependent_slice_segment_flag = get_bits1(gb);

                else

                    sh->dependent_slice_segment_flag = 0;

                slice_address_length = av_ceil_log2_c(h->sps->ctb_width *

                                                      h->sps->ctb_height);

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

                if (sh->slice_segment_addr >= h->sps->ctb_width * h->sps->ctb_height) {

                    av_log(h->avctx, AV_LOG_ERROR, "Invalid slice segment address: %u.\n",

                           sh->slice_segment_addr);

                    return AVERROR_INVALIDDATA;

                }

            } else

                sh->dependent_slice_segment_flag = 0;

            if (sh->dependent_slice_segment_flag)

                break;

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

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

            sh->slice_type = get_ue_golomb(gb);

            if (!(sh->slice_type == I_SLICE || sh->slice_type == P_SLICE ||

                  sh->slice_type == B_SLICE)) {

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

                       sh->slice_type);

                return AVERROR_INVALIDDATA;

            }

            s->pict_type = sh->slice_type == B_SLICE ? AV_PICTURE_TYPE_B :

                           sh->slice_type == P_SLICE ? AV_PICTURE_TYPE_P :

                                                       AV_PICTURE_TYPE_I;

            if (h->pps->output_flag_present_flag)

                sh->pic_output_flag = get_bits1(gb);

            if (h->sps->separate_colour_plane_flag)

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

            if (!IS_IDR(h)) {

                sh->pic_order_cnt_lsb = get_bits(gb, h->sps->log2_max_poc_lsb);

                s->output_picture_number = h->poc = ff_hevc_compute_poc(h, sh->pic_order_cnt_lsb);

            } else

                s->output_picture_number = h->poc = 0;

            if (h->temporal_id == 0 &&

                h->nal_unit_type != NAL_TRAIL_N &&

                h->nal_unit_type != NAL_TSA_N &&

                h->nal_unit_type != NAL_STSA_N &&

                h->nal_unit_type != NAL_RADL_N &&

                h->nal_unit_type != NAL_RASL_N &&

                h->nal_unit_type != NAL_RADL_R &&

                h->nal_unit_type != NAL_RASL_R)

                h->pocTid0 = h->poc;

            return 0; /* no need to evaluate the rest */

        }

        buf += consumed;

    }

    /* didn't find a picture! */

    av_log(h->avctx, AV_LOG_ERROR, "missing picture in access unit\n");

    return -1;

}


static void filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) {

    MpegEncContext * const s = &h->s;

    int mb_xy, mb_type;

    int qp, qp0, qp1, qpc, qpc0, qpc1, qp_thresh;

    mb_xy = mb_x + mb_y*s->mb_stride;

    if(mb_x==0 || mb_y==0 || !s->dsp.h264_loop_filter_strength ||

       (h->deblocking_filter == 2 && (h->slice_table[mb_xy] != h->slice_table[h->top_mb_xy] ||

                                      h->slice_table[mb_xy] != h->slice_table[mb_xy - 1]))) {

        filter_mb(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize);

        return;

    }

    assert(!FRAME_MBAFF);

    mb_type = s->current_picture.mb_type[mb_xy];

    qp = s->current_picture.qscale_table[mb_xy];

    qp0 = s->current_picture.qscale_table[mb_xy-1];

    qp1 = s->current_picture.qscale_table[h->top_mb_xy];

    qpc = get_chroma_qp( h, qp );

    qpc0 = get_chroma_qp( h, qp0 );

    qpc1 = get_chroma_qp( h, qp1 );

    qp0 = (qp + qp0 + 1) >> 1;

    qp1 = (qp + qp1 + 1) >> 1;

    qpc0 = (qpc + qpc0 + 1) >> 1;

    qpc1 = (qpc + qpc1 + 1) >> 1;

    qp_thresh = 15 - h->slice_alpha_c0_offset;

    if(qp <= qp_thresh && qp0 <= qp_thresh && qp1 <= qp_thresh &&

       qpc <= qp_thresh && qpc0 <= qp_thresh && qpc1 <= qp_thresh)

        return;

    if( IS_INTRA(mb_type) ) {

        int16_t bS4[4] = {4,4,4,4};

        int16_t bS3[4] = {3,3,3,3};

        if( IS_8x8DCT(mb_type) ) {

            filter_mb_edgev( h, &img_y[4*0], linesize, bS4, qp0 );

            filter_mb_edgev( h, &img_y[4*2], linesize, bS3, qp );

            filter_mb_edgeh( h, &img_y[4*0*linesize], linesize, bS4, qp1 );

            filter_mb_edgeh( h, &img_y[4*2*linesize], linesize, bS3, qp );

        } else {

            filter_mb_edgev( h, &img_y[4*0], linesize, bS4, qp0 );

            filter_mb_edgev( h, &img_y[4*1], linesize, bS3, qp );

            filter_mb_edgev( h, &img_y[4*2], linesize, bS3, qp );

            filter_mb_edgev( h, &img_y[4*3], linesize, bS3, qp );

            filter_mb_edgeh( h, &img_y[4*0*linesize], linesize, bS4, qp1 );

            filter_mb_edgeh( h, &img_y[4*1*linesize], linesize, bS3, qp );

            filter_mb_edgeh( h, &img_y[4*2*linesize], linesize, bS3, qp );

            filter_mb_edgeh( h, &img_y[4*3*linesize], linesize, bS3, qp );

        }

        filter_mb_edgecv( h, &img_cb[2*0], uvlinesize, bS4, qpc0 );

        filter_mb_edgecv( h, &img_cb[2*2], uvlinesize, bS3, qpc );

        filter_mb_edgecv( h, &img_cr[2*0], uvlinesize, bS4, qpc0 );

        filter_mb_edgecv( h, &img_cr[2*2], uvlinesize, bS3, qpc );

        filter_mb_edgech( h, &img_cb[2*0*uvlinesize], uvlinesize, bS4, qpc1 );

        filter_mb_edgech( h, &img_cb[2*2*uvlinesize], uvlinesize, bS3, qpc );

        filter_mb_edgech( h, &img_cr[2*0*uvlinesize], uvlinesize, bS4, qpc1 );

        filter_mb_edgech( h, &img_cr[2*2*uvlinesize], uvlinesize, bS3, qpc );

        return;

    } else {

        DECLARE_ALIGNED_8(int16_t, bS[2][4][4]);

        uint64_t (*bSv)[4] = (uint64_t(*)[4])bS;

        int edges;

        if( IS_8x8DCT(mb_type) && (h->cbp&7) == 7 ) {

            edges = 4;

            bSv[0][0] = bSv[0][2] = bSv[1][0] = bSv[1][2] = 0x0002000200020002ULL;

        } else {

            int mask_edge1 = (mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16)) ? 3 :

                             (mb_type & MB_TYPE_16x8) ? 1 : 0;

            int mask_edge0 = (mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16))

                             && (s->current_picture.mb_type[mb_xy-1] & (MB_TYPE_16x16 | MB_TYPE_8x16))

                             ? 3 : 0;

            int step = IS_8x8DCT(mb_type) ? 2 : 1;

            edges = (mb_type & MB_TYPE_16x16) && !(h->cbp & 15) ? 1 : 4;

            s->dsp.h264_loop_filter_strength( bS, h->non_zero_count_cache, h->ref_cache, h->mv_cache,

                                              (h->slice_type == B_TYPE), edges, step, mask_edge0, mask_edge1 );

        }

        if( IS_INTRA(s->current_picture.mb_type[mb_xy-1]) )

            bSv[0][0] = 0x0004000400040004ULL;

        if( IS_INTRA(s->current_picture.mb_type[h->top_mb_xy]) )

            bSv[1][0] = 0x0004000400040004ULL;

#define FILTER(hv,dir,edge)\

        if(bSv[dir][edge]) {\

            filter_mb_edge##hv( h, &img_y[4*edge*(dir?linesize:1)], linesize, bS[dir][edge], edge ? qp : qp##dir );\

            if(!(edge&1)) {\

                filter_mb_edgec##hv( h, &img_cb[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir );\

                filter_mb_edgec##hv( h, &img_cr[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir );\

            }\

        }

        if( edges == 1 ) {

            FILTER(v,0,0);

            FILTER(h,1,0);

        } else if( IS_8x8DCT(mb_type) ) {

            FILTER(v,0,0);

            FILTER(v,0,2);

            FILTER(h,1,0);

            FILTER(h,1,2);

        } else {

            FILTER(v,0,0);

            FILTER(v,0,1);

            FILTER(v,0,2);

            FILTER(v,0,3);

            FILTER(h,1,0);

            FILTER(h,1,1);

            FILTER(h,1,2);

            FILTER(h,1,3);

        }

#undef FILTER

    }

}


static int decode_frame_header(NUTContext *nut, int64_t *pts, int *stream_id,

                               uint8_t *header_idx, int frame_code)

{

    AVFormatContext *s = nut->avf;

    AVIOContext *bc    = s->pb;

    StreamContext *stc;

    int size, flags, size_mul, pts_delta, i, reserved_count;

    uint64_t tmp;

    if (avio_tell(bc) > nut->last_syncpoint_pos + nut->max_distance) {

        av_log(s, AV_LOG_ERROR,

               "Last frame must have been damaged %"PRId64" > %"PRId64" + %d\n",

               avio_tell(bc), nut->last_syncpoint_pos, nut->max_distance);

        return AVERROR_INVALIDDATA;

    }

    flags          = nut->frame_code[frame_code].flags;

    size_mul       = nut->frame_code[frame_code].size_mul;

    size           = nut->frame_code[frame_code].size_lsb;

    *stream_id     = nut->frame_code[frame_code].stream_id;

    pts_delta      = nut->frame_code[frame_code].pts_delta;

    reserved_count = nut->frame_code[frame_code].reserved_count;

    *header_idx    = nut->frame_code[frame_code].header_idx;

    if (flags & FLAG_INVALID)

        return AVERROR_INVALIDDATA;

    if (flags & FLAG_CODED)

        flags ^= ffio_read_varlen(bc);

    if (flags & FLAG_STREAM_ID) {

        GET_V(*stream_id, tmp < s->nb_streams);

    }

    stc = &nut->stream[*stream_id];

    if (flags & FLAG_CODED_PTS) {

        int coded_pts = ffio_read_varlen(bc);

        // FIXME check last_pts validity?

        if (coded_pts < (1 << stc->msb_pts_shift)) {

            *pts = ff_lsb2full(stc, coded_pts);

        } else

            *pts = coded_pts - (1 << stc->msb_pts_shift);

    } else

        *pts = stc->last_pts + pts_delta;

    if (flags & FLAG_SIZE_MSB)

        size += size_mul * ffio_read_varlen(bc);

    if (flags & FLAG_MATCH_TIME)

        get_s(bc);

    if (flags & FLAG_HEADER_IDX)

        *header_idx = ffio_read_varlen(bc);

    if (flags & FLAG_RESERVED)

        reserved_count = ffio_read_varlen(bc);

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

        ffio_read_varlen(bc);

    if (*header_idx >= (unsigned)nut->header_count) {

        av_log(s, AV_LOG_ERROR, "header_idx invalid\n");

        return AVERROR_INVALIDDATA;

    }

    if (size > 4096)

        *header_idx = 0;

    size -= nut->header_len[*header_idx];

    if (flags & FLAG_CHECKSUM) {

        avio_rb32(bc); // FIXME check this

    } else if (size > 2 * nut->max_distance || FFABS(stc->last_pts - *pts) >

               stc->max_pts_distance) {

        av_log(s, AV_LOG_ERROR, "frame size > 2max_distance and no checksum\n");

        return AVERROR_INVALIDDATA;

    }

    stc->last_pts   = *pts;

    stc->last_flags = flags;

    return size;

}


static int vmstate_n_elems(void *opaque, VMStateField *field)

{

    int n_elems = 1;

    if (field->flags & VMS_ARRAY) {

        n_elems = field->num;

    } else if (field->flags & VMS_VARRAY_INT32) {

        n_elems = *(int32_t *)(opaque+field->num_offset);

    } else if (field->flags & VMS_VARRAY_UINT32) {

        n_elems = *(uint32_t *)(opaque+field->num_offset);

    } else if (field->flags & VMS_VARRAY_UINT16) {

        n_elems = *(uint16_t *)(opaque+field->num_offset);

    } else if (field->flags & VMS_VARRAY_UINT8) {

        n_elems = *(uint8_t *)(opaque+field->num_offset);

    }

    return n_elems;

}


static void mm_decode_intra(MmContext * s, int half_horiz, int half_vert, const uint8_t *buf, int buf_size)
{
    int i, x, y;
    i=0; x=0; y=0;
    while(i<buf_size) {
        int run_length, color;
        if (buf[i] & 0x80) {
            run_length = 1;
            color = buf[i];
            i++;
        }else{
            run_length = (buf[i] & 0x7f) + 2;
            color = buf[i+1];
            i+=2;
        }
        if (half_horiz)
            run_length *=2;
        if (color) {
            memset(s->frame.data[0] + y*s->frame.linesize[0] + x, color, run_length);
            if (half_vert)
                memset(s->frame.data[0] + (y+1)*s->frame.linesize[0] + x, color, run_length);
        }
        x+= run_length;
        if (x >= s->avctx->width) {
            x=0;
            y += 1 + half_vert;
        }
    }
}


static void dnxhd_decode_dct_block_10_444(const DNXHDContext *ctx,

                                          RowContext *row, int n)

{

    dnxhd_decode_dct_block(ctx, row, n, 6, 32, 6);

}


int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)

{

    int ret;

#ifdef CONFIG_ACCEPT4

    ret = accept4(s, addr, addrlen, SOCK_CLOEXEC);

#else

    ret = accept(s, addr, addrlen);

    if (ret >= 0) {

        qemu_set_cloexec(ret);

    }

#endif

    return ret;

}


static int aac_decode_frame(AVCodecContext * avccontext, void * data, int * data_size, const uint8_t * buf, int buf_size) {

    AACContext * ac = avccontext->priv_data;

    GetBitContext gb;

    enum RawDataBlockType elem_type;

    int err, elem_id, data_size_tmp;

    init_get_bits(&gb, buf, buf_size*8);

    if (show_bits(&gb, 12) == 0xfff) {

        if ((err = parse_adts_frame_header(ac, &gb)) < 0) {

            av_log(avccontext, AV_LOG_ERROR, "Error decoding AAC frame header.\n");

            return -1;

        }

        if (ac->m4ac.sampling_index > 11) {

            av_log(ac->avccontext, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->m4ac.sampling_index);

            return -1;

        }

    }

    // parse

    while ((elem_type = get_bits(&gb, 3)) != TYPE_END) {

        elem_id = get_bits(&gb, 4);

        err = -1;

        if(elem_type == TYPE_SCE && elem_id == 1 &&

                !ac->che[TYPE_SCE][elem_id] && ac->che[TYPE_LFE][0]) {

            /* Some streams incorrectly code 5.1 audio as SCE[0] CPE[0] CPE[1] SCE[1]

               instead of SCE[0] CPE[0] CPE[0] LFE[0]. If we seem to have

               encountered such a stream, transfer the LFE[0] element to SCE[1] */

            ac->che[TYPE_SCE][elem_id] = ac->che[TYPE_LFE][0];

            ac->che[TYPE_LFE][0] = NULL;

        }

        if(elem_type < TYPE_DSE) {

            if(!ac->che[elem_type][elem_id])

                return -1;

            if(elem_type != TYPE_CCE)

                ac->che[elem_type][elem_id]->coup.coupling_point = 4;

        }

        switch (elem_type) {

        case TYPE_SCE:

            err = decode_ics(ac, &ac->che[TYPE_SCE][elem_id]->ch[0], &gb, 0, 0);

            break;

        case TYPE_CPE:

            err = decode_cpe(ac, &gb, elem_id);

            break;

        case TYPE_CCE:

            err = decode_cce(ac, &gb, ac->che[TYPE_CCE][elem_id]);

            break;

        case TYPE_LFE:

            err = decode_ics(ac, &ac->che[TYPE_LFE][elem_id]->ch[0], &gb, 0, 0);

            break;

        case TYPE_DSE:

            skip_data_stream_element(&gb);

            err = 0;

            break;

        case TYPE_PCE:

        {

            enum ChannelPosition new_che_pos[4][MAX_ELEM_ID];

            memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));

            if((err = decode_pce(ac, new_che_pos, &gb)))

                break;

            err = output_configure(ac, ac->che_pos, new_che_pos);

            break;

        }

        case TYPE_FIL:

            if (elem_id == 15)

                elem_id += get_bits(&gb, 8) - 1;

            while (elem_id > 0)

                elem_id -= decode_extension_payload(ac, &gb, elem_id);

            err = 0; /* FIXME */

            break;

        default:

            err = -1; /* should not happen, but keeps compiler happy */

            break;

        }

        if(err)

            return err;

    }

    spectral_to_sample(ac);

    if (!ac->is_saved) {

        ac->is_saved = 1;

        *data_size = 0;

        return buf_size;

    }

    data_size_tmp = 1024 * avccontext->channels * sizeof(int16_t);

    if(*data_size < data_size_tmp) {

        av_log(avccontext, AV_LOG_ERROR,

               "Output buffer too small (%d) or trying to output too many samples (%d) for this frame.\n",

               *data_size, data_size_tmp);

        return -1;

    }

    *data_size = data_size_tmp;

    ac->dsp.float_to_int16_interleave(data, (const float **)ac->output_data, 1024, avccontext->channels);

    return buf_size;

}


void ff_h264dsp_init(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)

{

#undef FUNC

#define FUNC(a, depth) a ## _ ## depth ## _c

#define ADDPX_DSP(depth) \

    c->h264_add_pixels4 = FUNC(ff_h264_add_pixels4, depth);\

    c->h264_add_pixels8 = FUNC(ff_h264_add_pixels8, depth)

    if (bit_depth > 8 && bit_depth <= 16) {

        ADDPX_DSP(16);

    } else {

        ADDPX_DSP(8);

    }

#define H264_DSP(depth) \

    c->h264_idct_add= FUNC(ff_h264_idct_add, depth);\

    c->h264_idct8_add= FUNC(ff_h264_idct8_add, depth);\

    c->h264_idct_dc_add= FUNC(ff_h264_idct_dc_add, depth);\

    c->h264_idct8_dc_add= FUNC(ff_h264_idct8_dc_add, depth);\

    c->h264_idct_add16     = FUNC(ff_h264_idct_add16, depth);\

    c->h264_idct8_add4     = FUNC(ff_h264_idct8_add4, depth);\

    if (chroma_format_idc == 1)\

        c->h264_idct_add8  = FUNC(ff_h264_idct_add8, depth);\

    else\

        c->h264_idct_add8  = FUNC(ff_h264_idct_add8_422, depth);\

    c->h264_idct_add16intra= FUNC(ff_h264_idct_add16intra, depth);\

    c->h264_luma_dc_dequant_idct= FUNC(ff_h264_luma_dc_dequant_idct, depth);\

    if (chroma_format_idc == 1)\

        c->h264_chroma_dc_dequant_idct= FUNC(ff_h264_chroma_dc_dequant_idct, depth);\

    else\

        c->h264_chroma_dc_dequant_idct= FUNC(ff_h264_chroma422_dc_dequant_idct, depth);\

\

    c->weight_h264_pixels_tab[0]= FUNC(weight_h264_pixels16, depth);\

    c->weight_h264_pixels_tab[1]= FUNC(weight_h264_pixels8, depth);\

    c->weight_h264_pixels_tab[2]= FUNC(weight_h264_pixels4, depth);\

    c->weight_h264_pixels_tab[3]= FUNC(weight_h264_pixels2, depth);\

    c->biweight_h264_pixels_tab[0]= FUNC(biweight_h264_pixels16, depth);\

    c->biweight_h264_pixels_tab[1]= FUNC(biweight_h264_pixels8, depth);\

    c->biweight_h264_pixels_tab[2]= FUNC(biweight_h264_pixels4, depth);\

    c->biweight_h264_pixels_tab[3]= FUNC(biweight_h264_pixels2, depth);\

\

    c->h264_v_loop_filter_luma= FUNC(h264_v_loop_filter_luma, depth);\

    c->h264_h_loop_filter_luma= FUNC(h264_h_loop_filter_luma, depth);\

    c->h264_h_loop_filter_luma_mbaff= FUNC(h264_h_loop_filter_luma_mbaff, depth);\

    c->h264_v_loop_filter_luma_intra= FUNC(h264_v_loop_filter_luma_intra, depth);\

    c->h264_h_loop_filter_luma_intra= FUNC(h264_h_loop_filter_luma_intra, depth);\

    c->h264_h_loop_filter_luma_mbaff_intra= FUNC(h264_h_loop_filter_luma_mbaff_intra, depth);\

    c->h264_v_loop_filter_chroma= FUNC(h264_v_loop_filter_chroma, depth);\

    if (chroma_format_idc == 1)\

        c->h264_h_loop_filter_chroma= FUNC(h264_h_loop_filter_chroma, depth);\

    else\

        c->h264_h_loop_filter_chroma= FUNC(h264_h_loop_filter_chroma422, depth);\

    if (chroma_format_idc == 1)\

        c->h264_h_loop_filter_chroma_mbaff= FUNC(h264_h_loop_filter_chroma_mbaff, depth);\

    else\

        c->h264_h_loop_filter_chroma_mbaff= FUNC(h264_h_loop_filter_chroma422_mbaff, depth);\

    c->h264_v_loop_filter_chroma_intra= FUNC(h264_v_loop_filter_chroma_intra, depth);\

    if (chroma_format_idc == 1)\

        c->h264_h_loop_filter_chroma_intra= FUNC(h264_h_loop_filter_chroma_intra, depth);\

    else\

        c->h264_h_loop_filter_chroma_intra= FUNC(h264_h_loop_filter_chroma422_intra, depth);\

    if (chroma_format_idc == 1)\

        c->h264_h_loop_filter_chroma_mbaff_intra= FUNC(h264_h_loop_filter_chroma_mbaff_intra, depth);\

    else\

        c->h264_h_loop_filter_chroma_mbaff_intra= FUNC(h264_h_loop_filter_chroma422_mbaff_intra, depth);\

    c->h264_loop_filter_strength= NULL;

    switch (bit_depth) {

    case 9:

        H264_DSP(9);

        break;

    case 10:

        H264_DSP(10);

        break;

    case 12:

        H264_DSP(12);

        break;

    case 14:

        H264_DSP(14);

        break;

    default:

        av_assert0(bit_depth<=8);

        H264_DSP(8);

        break;

    }

    if (ARCH_ARM) ff_h264dsp_init_arm(c, bit_depth, chroma_format_idc);

    if (HAVE_ALTIVEC) ff_h264dsp_init_ppc(c, bit_depth, chroma_format_idc);

    if (ARCH_X86) ff_h264dsp_init_x86(c, bit_depth, chroma_format_idc);

}


int redir_open(AVFormatContext **ic_ptr, ByteIOContext *f)

{

    char buf[4096], *q;

    int c;

    AVFormatContext *ic = NULL;

    /* parse each URL and try to open it */

    c = url_fgetc(f);

    while (c != URL_EOF) {

        /* skip spaces */

        for(;;) {

            if (!redir_isspace(c))

                break;

            c = url_fgetc(f);

        }

        if (c == URL_EOF)

            break;

        /* record url */

        q = buf;

        for(;;) {

            if (c == URL_EOF || redir_isspace(c))

                break;

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

                *q++ = c;

            c = url_fgetc(f);

        }

        *q = '\0';

        //printf("URL='%s'\n", buf);

        /* try to open the media file */

        if (av_open_input_file(&ic, buf, NULL, 0, NULL) == 0)

            break;

    }

    *ic_ptr = ic;

    if (!ic)

        return AVERROR(EIO);

    else

        return 0;

}


static int common_init(AVCodecContext *avctx){

    SnowContext *s = avctx->priv_data;

    int width, height;

    int level, orientation, plane_index, dec;

    s->avctx= avctx;

    dsputil_init(&s->dsp, avctx);

#define mcf(dx,dy)\

    s->dsp.put_qpel_pixels_tab       [0][dy+dx/4]=\

    s->dsp.put_no_rnd_qpel_pixels_tab[0][dy+dx/4]=\

        mc_block ## dx ## dy;

    mcf( 0, 0)

    mcf( 4, 0)

    mcf( 8, 0)

    mcf(12, 0)

    mcf( 0, 4)

    mcf( 4, 4)

    mcf( 8, 4)

    mcf(12, 4)

    mcf( 0, 8)

    mcf( 4, 8)

    mcf( 8, 8)

    mcf(12, 8)

    mcf( 0,12)

    mcf( 4,12)

    mcf( 8,12)

    mcf(12,12)

#define mcfh(dx,dy)\

    s->dsp.put_pixels_tab       [0][dy/4+dx/8]=\

    s->dsp.put_no_rnd_pixels_tab[0][dy/4+dx/8]=\

        mc_block_hpel ## dx ## dy;

    mcfh(0, 0)

    mcfh(8, 0)

    mcfh(0, 8)

    mcfh(8, 8)

    dec= s->spatial_decomposition_count= 5;

    s->spatial_decomposition_type= avctx->prediction_method; //FIXME add decorrelator type r transform_type

    s->chroma_h_shift= 1; //FIXME XXX

    s->chroma_v_shift= 1;

//    dec += FFMAX(s->chroma_h_shift, s->chroma_v_shift);

    s->b_width = (s->avctx->width +(1<<dec)-1)>>dec;

    s->b_height= (s->avctx->height+(1<<dec)-1)>>dec;

    s->spatial_dwt_buffer= av_mallocz(s->b_width*s->b_height*sizeof(DWTELEM)<<(2*dec));

    s->pred_buffer= av_mallocz(s->b_width*s->b_height*sizeof(DWTELEM)<<(2*dec));

    s->mv_scale= (s->avctx->flags & CODEC_FLAG_QPEL) ? 2 : 4;

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

        int w= s->avctx->width;

        int h= s->avctx->height;

        if(plane_index){

            w>>= s->chroma_h_shift;

            h>>= s->chroma_v_shift;

        }

        s->plane[plane_index].width = w;

        s->plane[plane_index].height= h;

//av_log(NULL, AV_LOG_DEBUG, "%d %d\n", w, h);

        for(level=s->spatial_decomposition_count-1; level>=0; level--){

            for(orientation=level ? 1 : 0; orientation<4; orientation++){

                SubBand *b= &s->plane[plane_index].band[level][orientation];

                b->buf= s->spatial_dwt_buffer;

                b->level= level;

                b->stride= s->plane[plane_index].width << (s->spatial_decomposition_count - level);

                b->width = (w + !(orientation&1))>>1;

                b->height= (h + !(orientation>1))>>1;

                if(orientation&1) b->buf += (w+1)>>1;

                if(orientation>1) b->buf += b->stride>>1;

                if(level)

                    b->parent= &s->plane[plane_index].band[level-1][orientation];

            }

            w= (w+1)>>1;

            h= (h+1)>>1;

        }

    }

    //FIXME init_subband() ?

    s->mb_band.stride= s->mv_band[0].stride= s->mv_band[1].stride=

    s->mb_band.width = s->mv_band[0].width = s->mv_band[1].width = (s->avctx->width + 15)>>4;

    s->mb_band.height= s->mv_band[0].height= s->mv_band[1].height= (s->avctx->height+ 15)>>4;

    s->mb_band   .buf= av_mallocz(s->mb_band   .stride * s->mb_band   .height*sizeof(DWTELEM));

    s->mv_band[0].buf= av_mallocz(s->mv_band[0].stride * s->mv_band[0].height*sizeof(DWTELEM));

    s->mv_band[1].buf= av_mallocz(s->mv_band[1].stride * s->mv_band[1].height*sizeof(DWTELEM));

    reset_contexts(s);

/*

    width= s->width= avctx->width;

    height= s->height= avctx->height;

    assert(width && height);

*/

    s->avctx->get_buffer(s->avctx, &s->mconly_picture);

    return 0;

}


USBDevice *usbdevice_create(const char *cmdline)

{

    USBBus *bus = usb_bus_find(-1 /* any */);

    DeviceInfo *info;

    USBDeviceInfo *usb;

    char driver[32];

    const char *params;

    int len;

    params = strchr(cmdline,':');

    if (params) {

        params++;

        len = params - cmdline;

        if (len > sizeof(driver))

            len = sizeof(driver);

        pstrcpy(driver, len, cmdline);

    } else {

        params = "";

        pstrcpy(driver, sizeof(driver), cmdline);

    }

    for (info = device_info_list; info != NULL; info = info->next) {

        if (info->bus_info != &usb_bus_info)

            continue;

        usb = DO_UPCAST(USBDeviceInfo, qdev, info);

        if (usb->usbdevice_name == NULL)

            continue;

        if (strcmp(usb->usbdevice_name, driver) != 0)

            continue;

        break;

    }

    if (info == NULL) {

#if 0

        /* no error because some drivers are not converted (yet) */

        error_report("usbdevice %s not found", driver);

#endif

        return NULL;

    }

    if (!usb->usbdevice_init) {

        if (params) {

            error_report("usbdevice %s accepts no params", driver);

            return NULL;

        }

        return usb_create_simple(bus, usb->qdev.name);

    }

    return usb->usbdevice_init(params);

}


static int net_init_nic(QemuOpts *opts,

                        Monitor *mon,

                        const char *name,

                        VLANState *vlan)

{

    int idx;

    NICInfo *nd;

    const char *netdev;

    idx = nic_get_free_idx();

    if (idx == -1 || nb_nics >= MAX_NICS) {

        qemu_error("Too Many NICs\n");

        return -1;

    }

    nd = &nd_table[idx];

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

    if ((netdev = qemu_opt_get(opts, "netdev"))) {

        nd->netdev = qemu_find_netdev(netdev);

        if (!nd->netdev) {

            qemu_error("netdev '%s' not found\n", netdev);

            return -1;

        }

    } else {

        assert(vlan);

        nd->vlan = vlan;

    }

    if (name) {

        nd->name = qemu_strdup(name);

    }

    if (qemu_opt_get(opts, "model")) {

        nd->model = qemu_strdup(qemu_opt_get(opts, "model"));

    }

    if (qemu_opt_get(opts, "addr")) {

        nd->devaddr = qemu_strdup(qemu_opt_get(opts, "addr"));

    }

    nd->macaddr[0] = 0x52;

    nd->macaddr[1] = 0x54;

    nd->macaddr[2] = 0x00;

    nd->macaddr[3] = 0x12;

    nd->macaddr[4] = 0x34;

    nd->macaddr[5] = 0x56 + idx;

    if (qemu_opt_get(opts, "macaddr") &&

        net_parse_macaddr(nd->macaddr, qemu_opt_get(opts, "macaddr")) < 0) {

        qemu_error("invalid syntax for ethernet address\n");

        return -1;

    }

    nd->nvectors = qemu_opt_get_number(opts, "vectors", NIC_NVECTORS_UNSPECIFIED);

    if (nd->nvectors != NIC_NVECTORS_UNSPECIFIED &&

        (nd->nvectors < 0 || nd->nvectors > 0x7ffffff)) {

        qemu_error("invalid # of vectors: %d\n", nd->nvectors);

        return -1;

    }

    nd->used = 1;

    if (vlan) {

        nd->vlan->nb_guest_devs++;

    }

    nb_nics++;

    return idx;

}