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

                              int *got_frame_ptr, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    ADPCMDecodeContext *c = avctx->priv_data;

    ADPCMChannelStatus *cs;

    int n, m, channel, i;

    short *samples;

    int16_t **samples_p;

    int st; /* stereo */

    int count1, count2;

    int nb_samples, coded_samples, ret;

    GetByteContext gb;

    bytestream2_init(&gb, buf, buf_size);

    nb_samples = get_nb_samples(avctx, &gb, buf_size, &coded_samples);

    if (nb_samples <= 0) {

        av_log(avctx, AV_LOG_ERROR, "invalid number of samples in packet\n");

        return AVERROR_INVALIDDATA;

    }

    /* get output buffer */

    c->frame.nb_samples = nb_samples;

    if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) {

        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");

        return ret;

    }

    samples = (short *)c->frame.data[0];

    samples_p = (int16_t **)c->frame.extended_data;

    /* use coded_samples when applicable */

    /* it is always <= nb_samples, so the output buffer will be large enough */

    if (coded_samples) {

        if (coded_samples != nb_samples)

            av_log(avctx, AV_LOG_WARNING, "mismatch in coded sample count\n");

        c->frame.nb_samples = nb_samples = coded_samples;

    }

    st = avctx->channels == 2 ? 1 : 0;

    switch(avctx->codec->id) {

    case AV_CODEC_ID_ADPCM_IMA_QT:

        /* In QuickTime, IMA is encoded by chunks of 34 bytes (=64 samples).

           Channel data is interleaved per-chunk. */

        for (channel = 0; channel < avctx->channels; channel++) {

            int predictor;

            int step_index;

            cs = &(c->status[channel]);

            /* (pppppp) (piiiiiii) */

            /* Bits 15-7 are the _top_ 9 bits of the 16-bit initial predictor value */

            predictor = sign_extend(bytestream2_get_be16u(&gb), 16);

            step_index = predictor & 0x7F;

            predictor &= ~0x7F;

            if (cs->step_index == step_index) {

                int diff = predictor - cs->predictor;

                if (diff < 0)

                    diff = - diff;

                if (diff > 0x7f)

                    goto update;

            } else {

            update:

                cs->step_index = step_index;

                cs->predictor = predictor;

            }

            if (cs->step_index > 88u){

                av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n",

                       channel, cs->step_index);

                return AVERROR_INVALIDDATA;

            }

            samples = samples_p[channel];

            for (m = 0; m < 64; m += 2) {

                int byte = bytestream2_get_byteu(&gb);

                samples[m    ] = adpcm_ima_qt_expand_nibble(cs, byte & 0x0F, 3);

                samples[m + 1] = adpcm_ima_qt_expand_nibble(cs, byte >> 4  , 3);

            }

        }

        break;

    case AV_CODEC_ID_ADPCM_IMA_WAV:

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

            cs = &(c->status[i]);

            cs->predictor = samples_p[i][0] = sign_extend(bytestream2_get_le16u(&gb), 16);

            cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16);

            if (cs->step_index > 88u){

                av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n",

                       i, cs->step_index);

                return AVERROR_INVALIDDATA;

            }

        }

        for (n = 0; n < (nb_samples - 1) / 8; n++) {

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

                cs = &c->status[i];

                samples = &samples_p[i][1 + n * 8];

                for (m = 0; m < 8; m += 2) {

                    int v = bytestream2_get_byteu(&gb);

                    samples[m    ] = adpcm_ima_expand_nibble(cs, v & 0x0F, 3);

                    samples[m + 1] = adpcm_ima_expand_nibble(cs, v >> 4  , 3);

                }

            }

        }

        break;

    case AV_CODEC_ID_ADPCM_4XM:

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

            c->status[i].predictor = sign_extend(bytestream2_get_le16u(&gb), 16);

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

            c->status[i].step_index = sign_extend(bytestream2_get_le16u(&gb), 16);

            if (c->status[i].step_index > 88u) {

                av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n",

                       i, c->status[i].step_index);

                return AVERROR_INVALIDDATA;

            }

        }

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

            samples = (int16_t *)c->frame.data[i];

            cs = &c->status[i];

            for (n = nb_samples >> 1; n > 0; n--) {

                int v = bytestream2_get_byteu(&gb);

                *samples++ = adpcm_ima_expand_nibble(cs, v & 0x0F, 4);

                *samples++ = adpcm_ima_expand_nibble(cs, v >> 4  , 4);

            }

        }

        break;

    case AV_CODEC_ID_ADPCM_MS:

    {

        int block_predictor;

        block_predictor = bytestream2_get_byteu(&gb);

        if (block_predictor > 6) {

            av_log(avctx, AV_LOG_ERROR, "ERROR: block_predictor[0] = %d\n",

                   block_predictor);

            return AVERROR_INVALIDDATA;

        }

        c->status[0].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor];

        c->status[0].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor];

        if (st) {

            block_predictor = bytestream2_get_byteu(&gb);

            if (block_predictor > 6) {

                av_log(avctx, AV_LOG_ERROR, "ERROR: block_predictor[1] = %d\n",

                       block_predictor);

                return AVERROR_INVALIDDATA;

            }

            c->status[1].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor];

            c->status[1].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor];

        }

        c->status[0].idelta = sign_extend(bytestream2_get_le16u(&gb), 16);

        if (st){

            c->status[1].idelta = sign_extend(bytestream2_get_le16u(&gb), 16);

        }

        c->status[0].sample1 = sign_extend(bytestream2_get_le16u(&gb), 16);

        if (st) c->status[1].sample1 = sign_extend(bytestream2_get_le16u(&gb), 16);

        c->status[0].sample2 = sign_extend(bytestream2_get_le16u(&gb), 16);

        if (st) c->status[1].sample2 = sign_extend(bytestream2_get_le16u(&gb), 16);

        *samples++ = c->status[0].sample2;

        if (st) *samples++ = c->status[1].sample2;

        *samples++ = c->status[0].sample1;

        if (st) *samples++ = c->status[1].sample1;

        for(n = (nb_samples - 2) >> (1 - st); n > 0; n--) {

            int byte = bytestream2_get_byteu(&gb);

            *samples++ = adpcm_ms_expand_nibble(&c->status[0 ], byte >> 4  );

            *samples++ = adpcm_ms_expand_nibble(&c->status[st], byte & 0x0F);

        }

        break;

    }

    case AV_CODEC_ID_ADPCM_IMA_DK4:

        for (channel = 0; channel < avctx->channels; channel++) {

            cs = &c->status[channel];

            cs->predictor  = *samples++ = sign_extend(bytestream2_get_le16u(&gb), 16);

            cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16);

            if (cs->step_index > 88u){

                av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n",

                       channel, cs->step_index);

                return AVERROR_INVALIDDATA;

            }

        }

        for (n = nb_samples >> (1 - st); n > 0; n--) {

            int v = bytestream2_get_byteu(&gb);

            *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v >> 4  , 3);

            *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3);

        }

        break;

    case AV_CODEC_ID_ADPCM_IMA_DK3:

    {

        int last_byte = 0;

        int nibble;

        int decode_top_nibble_next = 0;

        int diff_channel;

        const int16_t *samples_end = samples + avctx->channels * nb_samples;

        bytestream2_skipu(&gb, 10);

        c->status[0].predictor  = sign_extend(bytestream2_get_le16u(&gb), 16);

        c->status[1].predictor  = sign_extend(bytestream2_get_le16u(&gb), 16);

        c->status[0].step_index = bytestream2_get_byteu(&gb);

        c->status[1].step_index = bytestream2_get_byteu(&gb);

        if (c->status[0].step_index > 88u || c->status[1].step_index > 88u){

            av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i/%i\n",

                   c->status[0].step_index, c->status[1].step_index);

            return AVERROR_INVALIDDATA;

        }

        /* sign extend the predictors */

        diff_channel = c->status[1].predictor;

        /* DK3 ADPCM support macro */

#define DK3_GET_NEXT_NIBBLE() \

    if (decode_top_nibble_next) { \

        nibble = last_byte >> 4; \

        decode_top_nibble_next = 0; \

    } else { \

        last_byte = bytestream2_get_byteu(&gb); \

        nibble = last_byte & 0x0F; \

        decode_top_nibble_next = 1; \

    }

        while (samples < samples_end) {

            /* for this algorithm, c->status[0] is the sum channel and

             * c->status[1] is the diff channel */

            /* process the first predictor of the sum channel */

            DK3_GET_NEXT_NIBBLE();

            adpcm_ima_expand_nibble(&c->status[0], nibble, 3);

            /* process the diff channel predictor */

            DK3_GET_NEXT_NIBBLE();

            adpcm_ima_expand_nibble(&c->status[1], nibble, 3);

            /* process the first pair of stereo PCM samples */

            diff_channel = (diff_channel + c->status[1].predictor) / 2;

            *samples++ = c->status[0].predictor + c->status[1].predictor;

            *samples++ = c->status[0].predictor - c->status[1].predictor;

            /* process the second predictor of the sum channel */

            DK3_GET_NEXT_NIBBLE();

            adpcm_ima_expand_nibble(&c->status[0], nibble, 3);

            /* process the second pair of stereo PCM samples */

            diff_channel = (diff_channel + c->status[1].predictor) / 2;

            *samples++ = c->status[0].predictor + c->status[1].predictor;

            *samples++ = c->status[0].predictor - c->status[1].predictor;

        }

        break;

    }

    case AV_CODEC_ID_ADPCM_IMA_ISS:

        for (channel = 0; channel < avctx->channels; channel++) {

            cs = &c->status[channel];

            cs->predictor  = sign_extend(bytestream2_get_le16u(&gb), 16);

            cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16);

            if (cs->step_index > 88u){

                av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n",

                       channel, cs->step_index);

                return AVERROR_INVALIDDATA;

            }

        }

        for (n = nb_samples >> (1 - st); n > 0; n--) {

            int v1, v2;

            int v = bytestream2_get_byteu(&gb);

            /* nibbles are swapped for mono */

            if (st) {

                v1 = v >> 4;

                v2 = v & 0x0F;

            } else {

                v2 = v >> 4;

                v1 = v & 0x0F;

            }

            *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v1, 3);

            *samples++ = adpcm_ima_expand_nibble(&c->status[st], v2, 3);

        }

        break;

    case AV_CODEC_ID_ADPCM_IMA_APC:

        while (bytestream2_get_bytes_left(&gb) > 0) {

            int v = bytestream2_get_byteu(&gb);

            *samples++ = adpcm_ima_expand_nibble(&c->status[0],  v >> 4  , 3);

            *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3);

        }

        break;

    case AV_CODEC_ID_ADPCM_IMA_OKI:

        while (bytestream2_get_bytes_left(&gb) > 0) {

            int v = bytestream2_get_byteu(&gb);

            *samples++ = adpcm_ima_oki_expand_nibble(&c->status[0],  v >> 4  );

            *samples++ = adpcm_ima_oki_expand_nibble(&c->status[st], v & 0x0F);

        }

        break;

    case AV_CODEC_ID_ADPCM_IMA_WS:

        if (c->vqa_version == 3) {

            for (channel = 0; channel < avctx->channels; channel++) {

                int16_t *smp = samples_p[channel];

                for (n = nb_samples / 2; n > 0; n--) {

                    int v = bytestream2_get_byteu(&gb);

                    *smp++ = adpcm_ima_expand_nibble(&c->status[channel], v >> 4  , 3);

                    *smp++ = adpcm_ima_expand_nibble(&c->status[channel], v & 0x0F, 3);

                }

            }

        } else {

            for (n = nb_samples / 2; n > 0; n--) {

                for (channel = 0; channel < avctx->channels; channel++) {

                    int v = bytestream2_get_byteu(&gb);

                    *samples++  = adpcm_ima_expand_nibble(&c->status[channel], v >> 4  , 3);

                    samples[st] = adpcm_ima_expand_nibble(&c->status[channel], v & 0x0F, 3);

                }

                samples += avctx->channels;

            }

        }

        bytestream2_seek(&gb, 0, SEEK_END);

        break;

    case AV_CODEC_ID_ADPCM_XA:

    {

        int16_t *out0 = samples_p[0];

        int16_t *out1 = samples_p[1];

        int samples_per_block = 28 * (3 - avctx->channels) * 4;

        int sample_offset = 0;

        while (bytestream2_get_bytes_left(&gb) >= 128) {

            if ((ret = xa_decode(avctx, out0, out1, buf + bytestream2_tell(&gb),

                                 &c->status[0], &c->status[1],

                                 avctx->channels, sample_offset)) < 0)

                return ret;

            bytestream2_skipu(&gb, 128);

            sample_offset += samples_per_block;

        }

        break;

    }

    case AV_CODEC_ID_ADPCM_IMA_EA_EACS:

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

            c->status[i].step_index = bytestream2_get_le32u(&gb);

            if (c->status[i].step_index > 88u) {

                av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n",

                       i, c->status[i].step_index);

                return AVERROR_INVALIDDATA;

            }

        }

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

            c->status[i].predictor  = bytestream2_get_le32u(&gb);

        for (n = nb_samples >> (1 - st); n > 0; n--) {

            int byte   = bytestream2_get_byteu(&gb);

            *samples++ = adpcm_ima_expand_nibble(&c->status[0],  byte >> 4,   3);

            *samples++ = adpcm_ima_expand_nibble(&c->status[st], byte & 0x0F, 3);

        }

        break;

    case AV_CODEC_ID_ADPCM_IMA_EA_SEAD:

        for (n = nb_samples >> (1 - st); n > 0; n--) {

            int byte = bytestream2_get_byteu(&gb);

            *samples++ = adpcm_ima_expand_nibble(&c->status[0],  byte >> 4,   6);

            *samples++ = adpcm_ima_expand_nibble(&c->status[st], byte & 0x0F, 6);

        }

        break;

    case AV_CODEC_ID_ADPCM_EA:

    {

        int previous_left_sample, previous_right_sample;

        int current_left_sample, current_right_sample;

        int next_left_sample, next_right_sample;

        int coeff1l, coeff2l, coeff1r, coeff2r;

        int shift_left, shift_right;

        /* Each EA ADPCM frame has a 12-byte header followed by 30-byte pieces,

           each coding 28 stereo samples. */

        if(avctx->channels != 2)

            return AVERROR_INVALIDDATA;

        current_left_sample   = sign_extend(bytestream2_get_le16u(&gb), 16);

        previous_left_sample  = sign_extend(bytestream2_get_le16u(&gb), 16);

        current_right_sample  = sign_extend(bytestream2_get_le16u(&gb), 16);

        previous_right_sample = sign_extend(bytestream2_get_le16u(&gb), 16);

        for (count1 = 0; count1 < nb_samples / 28; count1++) {

            int byte = bytestream2_get_byteu(&gb);

            coeff1l = ea_adpcm_table[ byte >> 4       ];

            coeff2l = ea_adpcm_table[(byte >> 4  ) + 4];

            coeff1r = ea_adpcm_table[ byte & 0x0F];

            coeff2r = ea_adpcm_table[(byte & 0x0F) + 4];

            byte = bytestream2_get_byteu(&gb);

            shift_left  = 20 - (byte >> 4);

            shift_right = 20 - (byte & 0x0F);

            for (count2 = 0; count2 < 28; count2++) {

                byte = bytestream2_get_byteu(&gb);

                next_left_sample  = sign_extend(byte >> 4, 4) << shift_left;

                next_right_sample = sign_extend(byte,      4) << shift_right;

                next_left_sample = (next_left_sample +

                    (current_left_sample * coeff1l) +

                    (previous_left_sample * coeff2l) + 0x80) >> 8;

                next_right_sample = (next_right_sample +

                    (current_right_sample * coeff1r) +

                    (previous_right_sample * coeff2r) + 0x80) >> 8;

                previous_left_sample = current_left_sample;

                current_left_sample = av_clip_int16(next_left_sample);

                previous_right_sample = current_right_sample;

                current_right_sample = av_clip_int16(next_right_sample);

                *samples++ = current_left_sample;

                *samples++ = current_right_sample;

            }

        }

        bytestream2_skip(&gb, 2); // Skip terminating 0x0000

        break;

    }

    case AV_CODEC_ID_ADPCM_EA_MAXIS_XA:

    {

        int coeff[2][2], shift[2];

        for(channel = 0; channel < avctx->channels; channel++) {

            int byte = bytestream2_get_byteu(&gb);

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

                coeff[channel][i] = ea_adpcm_table[(byte >> 4) + 4*i];

            shift[channel] = 20 - (byte & 0x0F);

        }

        for (count1 = 0; count1 < nb_samples / 2; count1++) {

            int byte[2];

            byte[0] = bytestream2_get_byteu(&gb);

            if (st) byte[1] = bytestream2_get_byteu(&gb);

            for(i = 4; i >= 0; i-=4) { /* Pairwise samples LL RR (st) or LL LL (mono) */

                for(channel = 0; channel < avctx->channels; channel++) {

                    int sample = sign_extend(byte[channel] >> i, 4) << shift[channel];

                    sample = (sample +

                             c->status[channel].sample1 * coeff[channel][0] +

                             c->status[channel].sample2 * coeff[channel][1] + 0x80) >> 8;

                    c->status[channel].sample2 = c->status[channel].sample1;

                    c->status[channel].sample1 = av_clip_int16(sample);

                    *samples++ = c->status[channel].sample1;

                }

            }

        }

        bytestream2_seek(&gb, 0, SEEK_END);

        break;

    }

    case AV_CODEC_ID_ADPCM_EA_R1:

    case AV_CODEC_ID_ADPCM_EA_R2:

    case AV_CODEC_ID_ADPCM_EA_R3: {

        /* channel numbering

           2chan: 0=fl, 1=fr

           4chan: 0=fl, 1=rl, 2=fr, 3=rr

           6chan: 0=fl, 1=c,  2=fr, 3=rl,  4=rr, 5=sub */

        const int big_endian = avctx->codec->id == AV_CODEC_ID_ADPCM_EA_R3;

        int previous_sample, current_sample, next_sample;

        int coeff1, coeff2;

        int shift;

        unsigned int channel;

        uint16_t *samplesC;

        int count = 0;

        int offsets[6];

        for (channel=0; channel<avctx->channels; channel++)

            offsets[channel] = (big_endian ? bytestream2_get_be32(&gb) :

                                             bytestream2_get_le32(&gb)) +

                               (avctx->channels + 1) * 4;

        for (channel=0; channel<avctx->channels; channel++) {

            bytestream2_seek(&gb, offsets[channel], SEEK_SET);

            samplesC = samples_p[channel];

            if (avctx->codec->id == AV_CODEC_ID_ADPCM_EA_R1) {

                current_sample  = sign_extend(bytestream2_get_le16(&gb), 16);

                previous_sample = sign_extend(bytestream2_get_le16(&gb), 16);

            } else {

                current_sample  = c->status[channel].predictor;

                previous_sample = c->status[channel].prev_sample;

            }

            for (count1 = 0; count1 < nb_samples / 28; count1++) {

                int byte = bytestream2_get_byte(&gb);

                if (byte == 0xEE) {  /* only seen in R2 and R3 */

                    current_sample  = sign_extend(bytestream2_get_be16(&gb), 16);

                    previous_sample = sign_extend(bytestream2_get_be16(&gb), 16);

                    for (count2=0; count2<28; count2++)

                        *samplesC++ = sign_extend(bytestream2_get_be16(&gb), 16);

                } else {

                    coeff1 = ea_adpcm_table[ byte >> 4     ];

                    coeff2 = ea_adpcm_table[(byte >> 4) + 4];

                    shift = 20 - (byte & 0x0F);

                    for (count2=0; count2<28; count2++) {

                        if (count2 & 1)

                            next_sample = sign_extend(byte,    4) << shift;

                        else {

                            byte = bytestream2_get_byte(&gb);

                            next_sample = sign_extend(byte >> 4, 4) << shift;

                        }

                        next_sample += (current_sample  * coeff1) +

                                       (previous_sample * coeff2);

                        next_sample = av_clip_int16(next_sample >> 8);

                        previous_sample = current_sample;

                        current_sample  = next_sample;

                        *samplesC++ = current_sample;

                    }

                }

            }

            if (!count) {

                count = count1;

            } else if (count != count1) {

                av_log(avctx, AV_LOG_WARNING, "per-channel sample count mismatch\n");

                count = FFMAX(count, count1);

            }

            if (avctx->codec->id != AV_CODEC_ID_ADPCM_EA_R1) {

                c->status[channel].predictor   = current_sample;

                c->status[channel].prev_sample = previous_sample;

            }

        }

        c->frame.nb_samples = count * 28;

        bytestream2_seek(&gb, 0, SEEK_END);

        break;

    }

    case AV_CODEC_ID_ADPCM_EA_XAS:

        for (channel=0; channel<avctx->channels; channel++) {

            int coeff[2][4], shift[4];

            int16_t *s = samples_p[channel];

            for (n = 0; n < 4; n++, s += 32) {

                int val = sign_extend(bytestream2_get_le16u(&gb), 16);

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

                    coeff[i][n] = ea_adpcm_table[(val&0x0F)+4*i];

                s[0] = val & ~0x0F;

                val = sign_extend(bytestream2_get_le16u(&gb), 16);

                shift[n] = 20 - (val & 0x0F);

                s[1] = val & ~0x0F;

            }

            for (m=2; m<32; m+=2) {

                s = &samples_p[channel][m];

                for (n = 0; n < 4; n++, s += 32) {

                    int level, pred;

                    int byte = bytestream2_get_byteu(&gb);

                    level = sign_extend(byte >> 4, 4) << shift[n];

                    pred  = s[-1] * coeff[0][n] + s[-2] * coeff[1][n];

                    s[0]  = av_clip_int16((level + pred + 0x80) >> 8);

                    level = sign_extend(byte, 4) << shift[n];

                    pred  = s[0] * coeff[0][n] + s[-1] * coeff[1][n];

                    s[1]  = av_clip_int16((level + pred + 0x80) >> 8);

                }

            }

        }

        break;

    case AV_CODEC_ID_ADPCM_IMA_AMV:

        c->status[0].predictor = sign_extend(bytestream2_get_le16u(&gb), 16);

        c->status[0].step_index = bytestream2_get_le16u(&gb);

        bytestream2_skipu(&gb, 4);

        if (c->status[0].step_index > 88u) {

            av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i\n",

                   c->status[0].step_index);

            return AVERROR_INVALIDDATA;

        }

        for (n = nb_samples >> (1 - st); n > 0; n--) {

            int v = bytestream2_get_byteu(&gb);

            *samples++ = adpcm_ima_expand_nibble(&c->status[0], v >> 4, 3);

            *samples++ = adpcm_ima_expand_nibble(&c->status[0], v & 0xf, 3);

        }

        break;

    case AV_CODEC_ID_ADPCM_IMA_SMJPEG:

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

            c->status[i].predictor = sign_extend(bytestream2_get_be16u(&gb), 16);

            c->status[i].step_index = bytestream2_get_byteu(&gb);

            bytestream2_skipu(&gb, 1);

            if (c->status[i].step_index > 88u) {

                av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i\n",

                       c->status[i].step_index);

                return AVERROR_INVALIDDATA;

            }

        }

        for (n = nb_samples >> (1 - st); n > 0; n--) {

            int v = bytestream2_get_byteu(&gb);

            *samples++ = adpcm_ima_qt_expand_nibble(&c->status[0 ], v >> 4, 3);

            *samples++ = adpcm_ima_qt_expand_nibble(&c->status[st], v & 0xf, 3);

        }

        break;

    case AV_CODEC_ID_ADPCM_CT:

        for (n = nb_samples >> (1 - st); n > 0; n--) {

            int v = bytestream2_get_byteu(&gb);

            *samples++ = adpcm_ct_expand_nibble(&c->status[0 ], v >> 4  );

            *samples++ = adpcm_ct_expand_nibble(&c->status[st], v & 0x0F);

        }

        break;

    case AV_CODEC_ID_ADPCM_SBPRO_4:

    case AV_CODEC_ID_ADPCM_SBPRO_3:

    case AV_CODEC_ID_ADPCM_SBPRO_2:

        if (!c->status[0].step_index) {

            /* the first byte is a raw sample */

            *samples++ = 128 * (bytestream2_get_byteu(&gb) - 0x80);

            if (st)

                *samples++ = 128 * (bytestream2_get_byteu(&gb) - 0x80);

            c->status[0].step_index = 1;

            nb_samples--;

        }

        if (avctx->codec->id == AV_CODEC_ID_ADPCM_SBPRO_4) {

            for (n = nb_samples >> (1 - st); n > 0; n--) {

                int byte = bytestream2_get_byteu(&gb);

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],

                                                       byte >> 4,   4, 0);

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[st],

                                                       byte & 0x0F, 4, 0);

            }

        } else if (avctx->codec->id == AV_CODEC_ID_ADPCM_SBPRO_3) {

            for (n = nb_samples / 3; n > 0; n--) {

                int byte = bytestream2_get_byteu(&gb);

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],

                                                        byte >> 5        , 3, 0);

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],

                                                       (byte >> 2) & 0x07, 3, 0);

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],

                                                        byte & 0x03,       2, 0);

            }

        } else {

            for (n = nb_samples >> (2 - st); n > 0; n--) {

                int byte = bytestream2_get_byteu(&gb);

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],

                                                        byte >> 6        , 2, 2);

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[st],

                                                       (byte >> 4) & 0x03, 2, 2);

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],

                                                       (byte >> 2) & 0x03, 2, 2);

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[st],

                                                        byte & 0x03,       2, 2);

            }

        }

        break;

    case AV_CODEC_ID_ADPCM_SWF:

        adpcm_swf_decode(avctx, buf, buf_size, samples);

        bytestream2_seek(&gb, 0, SEEK_END);

        break;

    case AV_CODEC_ID_ADPCM_YAMAHA:

        for (n = nb_samples >> (1 - st); n > 0; n--) {

            int v = bytestream2_get_byteu(&gb);

            *samples++ = adpcm_yamaha_expand_nibble(&c->status[0 ], v & 0x0F);

            *samples++ = adpcm_yamaha_expand_nibble(&c->status[st], v >> 4  );

        }

        break;

    case AV_CODEC_ID_ADPCM_AFC:

    {

        int samples_per_block;

        int blocks;

        if (avctx->extradata && avctx->extradata_size == 1 && avctx->extradata[0]) {

            samples_per_block = avctx->extradata[0] / 16;

            blocks = nb_samples / avctx->extradata[0];

        } else {

            samples_per_block = nb_samples / 16;

            blocks = 1;

        }

        for (m = 0; m < blocks; m++) {

        for (channel = 0; channel < avctx->channels; channel++) {

            int prev1 = c->status[channel].sample1;

            int prev2 = c->status[channel].sample2;

            samples = samples_p[channel] + m * 16;

            /* Read in every sample for this channel.  */

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

                int byte = bytestream2_get_byteu(&gb);

                int scale = 1 << (byte >> 4);

                int index = byte & 0xf;

                int factor1 = ff_adpcm_afc_coeffs[0][index];

                int factor2 = ff_adpcm_afc_coeffs[1][index];

                /* Decode 16 samples.  */

                for (n = 0; n < 16; n++) {

                    int32_t sampledat;

                    if (n & 1) {

                        sampledat = sign_extend(byte, 4);

                    } else {

                        byte = bytestream2_get_byteu(&gb);

                        sampledat = sign_extend(byte >> 4, 4);

                    }

                    sampledat = ((prev1 * factor1 + prev2 * factor2) +

                                 ((sampledat * scale) << 11)) >> 11;

                    *samples = av_clip_int16(sampledat);

                    prev2 = prev1;

                    prev1 = *samples++;

                }

            }

            c->status[channel].sample1 = prev1;

            c->status[channel].sample2 = prev2;

        }

        }

        bytestream2_seek(&gb, 0, SEEK_END);

        break;

    }

    case AV_CODEC_ID_ADPCM_THP:

    {

        int table[6][16];

        int ch;

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

            for (n = 0; n < 16; n++)

                table[i][n] = sign_extend(bytestream2_get_be16u(&gb), 16);

        /* Initialize the previous sample.  */

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

            c->status[i].sample1 = sign_extend(bytestream2_get_be16u(&gb), 16);

            c->status[i].sample2 = sign_extend(bytestream2_get_be16u(&gb), 16);

        }

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

            samples = samples_p[ch];

            /* Read in every sample for this channel.  */

            for (i = 0; i < nb_samples / 14; i++) {

                int byte = bytestream2_get_byteu(&gb);

                int index = (byte >> 4) & 7;

                unsigned int exp = byte & 0x0F;

                int factor1 = table[ch][index * 2];

                int factor2 = table[ch][index * 2 + 1];

                /* Decode 14 samples.  */

                for (n = 0; n < 14; n++) {

                    int32_t sampledat;

                    if (n & 1) {

                        sampledat = sign_extend(byte, 4);

                    } else {

                        byte = bytestream2_get_byteu(&gb);

                        sampledat = sign_extend(byte >> 4, 4);

                    }

                    sampledat = ((c->status[ch].sample1 * factor1

                                + c->status[ch].sample2 * factor2) >> 11) + (sampledat << exp);

                    *samples = av_clip_int16(sampledat);

                    c->status[ch].sample2 = c->status[ch].sample1;

                    c->status[ch].sample1 = *samples++;

                }

            }

        }

        break;

    }

    default:

        return -1;

    }

    if (avpkt->size && bytestream2_tell(&gb) == 0) {

        av_log(avctx, AV_LOG_ERROR, "Nothing consumed\n");

        return AVERROR_INVALIDDATA;

    }

    *got_frame_ptr   = 1;

    *(AVFrame *)data = c->frame;

    return bytestream2_tell(&gb);

}


static void usbredir_interrupt_packet(void *priv, uint32_t id,

    struct usb_redir_interrupt_packet_header *interrupt_packet,

    uint8_t *data, int data_len)

{

    USBRedirDevice *dev = priv;

    uint8_t ep = interrupt_packet->endpoint;

    DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",

            interrupt_packet->status, ep, data_len, id);

    if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {

        ERROR("received int packet for non interrupt endpoint %02X\n", ep);

        free(data);

        return;

    }

    if (ep & USB_DIR_IN) {

        if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {

            DPRINTF("received int packet while not started ep %02X\n", ep);

            free(data);

            return;

        }

        /* bufp_alloc also adds the packet to the ep queue */

        bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);

    } else {

        int len = interrupt_packet->length;

        AsyncURB *aurb = async_find(dev, id);

        if (!aurb) {

            return;

        }

        if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {

            ERROR("return int packet mismatch, please report this!\n");

            len = USB_RET_NAK;

        }

        if (aurb->packet) {

            aurb->packet->result = usbredir_handle_status(dev,

                                               interrupt_packet->status, len);

            usb_packet_complete(&dev->dev, aurb->packet);

        }

        async_free(dev, aurb);

    }

}


static int coroutine_fn nfs_co_readv(BlockDriverState *bs,

                                     int64_t sector_num, int nb_sectors,

                                     QEMUIOVector *iov)

{

    NFSClient *client = bs->opaque;

    NFSRPC task;

    nfs_co_init_task(client, &task);

    task.iov = iov;

    if (nfs_pread_async(client->context, client->fh,

                        sector_num * BDRV_SECTOR_SIZE,

                        nb_sectors * BDRV_SECTOR_SIZE,

                        nfs_co_generic_cb, &task) != 0) {

        return -ENOMEM;

    }

    while (!task.complete) {

        nfs_set_events(client);

        qemu_coroutine_yield();

    }

    if (task.ret < 0) {

        return task.ret;

    }

    /* zero pad short reads */

    if (task.ret < iov->size) {

        qemu_iovec_memset(iov, task.ret, 0, iov->size - task.ret);

    }

    return 0;

}


int scsi_req_parse(SCSIRequest *req, uint8_t *buf)

{

    int rc;

    if (req->dev->type == TYPE_TAPE) {

        rc = scsi_req_stream_length(&req->cmd, req->dev, buf);

    } else {

        rc = scsi_req_length(&req->cmd, req->dev, buf);

    }

    if (rc != 0)

        return rc;

    assert(buf == req->cmd.buf);

    scsi_cmd_xfer_mode(&req->cmd);

    req->cmd.lba = scsi_cmd_lba(&req->cmd);

    trace_scsi_req_parsed(req->dev->id, req->lun, req->tag, buf[0],

                          req->cmd.mode, req->cmd.xfer);

    if (req->cmd.lba != -1) {

        trace_scsi_req_parsed_lba(req->dev->id, req->lun, req->tag, buf[0],

                              req->cmd.lba);

    }

    return 0;

}


void virtqueue_map_sg(struct iovec *sg, hwaddr *addr,

    size_t num_sg, int is_write)

{

    unsigned int i;

    hwaddr len;

    if (num_sg >= VIRTQUEUE_MAX_SIZE) {

        error_report("virtio: map attempt out of bounds: %zd > %d",

                     num_sg, VIRTQUEUE_MAX_SIZE);

        exit(1);

    }

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

        len = sg[i].iov_len;

        sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write);

        if (sg[i].iov_base == NULL || len != sg[i].iov_len) {

            error_report("virtio: trying to map MMIO memory");

            exit(1);

        }

    }

}


static inline void gen_op_fcmpeq(int fccno)

{

    switch (fccno) {

    case 0:

        gen_helper_fcmpeq(cpu_env);

        break;

    case 1:

        gen_helper_fcmpeq_fcc1(cpu_env);

        break;

    case 2:

        gen_helper_fcmpeq_fcc2(cpu_env);

        break;

    case 3:

        gen_helper_fcmpeq_fcc3(cpu_env);

        break;

    }

}


static bool pc_machine_get_vmport(Object *obj, Error **errp)

{

    PCMachineState *pcms = PC_MACHINE(obj);

    return pcms->vmport;

}


pvscsi_convert_sglist(PVSCSIRequest *r)

{

    int chunk_size;

    uint64_t data_length = r->req.dataLen;

    PVSCSISGState sg = r->sg;

    while (data_length) {

        while (!sg.resid) {

            pvscsi_get_next_sg_elem(&sg);

            trace_pvscsi_convert_sglist(r->req.context, r->sg.dataAddr,

                                        r->sg.resid);

        }

        assert(data_length > 0);

        chunk_size = MIN((unsigned) data_length, sg.resid);

        if (chunk_size) {

            qemu_sglist_add(&r->sgl, sg.dataAddr, chunk_size);

        }

        sg.dataAddr += chunk_size;

        data_length -= chunk_size;

        sg.resid -= chunk_size;

    }

}


static void av_estimate_timings_from_pts(AVFormatContext *ic)

{

    AVPacket pkt1, *pkt = &pkt1;

    AVStream *st;

    int read_size, i, ret;

    int64_t start_time, end_time, end_time1;

    int64_t filesize, offset, duration;

    /* we read the first packets to get the first PTS (not fully

       accurate, but it is enough now) */

    url_fseek(&ic->pb, 0, SEEK_SET);

    read_size = 0;

    for(;;) {

        if (read_size >= DURATION_MAX_READ_SIZE)

            break;

        /* if all info is available, we can stop */

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

            st = ic->streams[i];

            if (st->start_time == AV_NOPTS_VALUE)

                break;

        }

        if (i == ic->nb_streams)

            break;

        ret = av_read_packet(ic, pkt);

        if (ret != 0)

            break;

        read_size += pkt->size;

        st = ic->streams[pkt->stream_index];

        if (pkt->pts != AV_NOPTS_VALUE) {

            if (st->start_time == AV_NOPTS_VALUE)

                st->start_time = (int64_t)((double)pkt->pts * ic->pts_num * (double)AV_TIME_BASE / ic->pts_den);

         }

         av_free_packet(pkt);

     }

    /* we compute the minimum start_time and use it as default */

    start_time = MAXINT64;

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

        st = ic->streams[i];

        if (st->start_time != AV_NOPTS_VALUE &&

            st->start_time < start_time)

            start_time = st->start_time;

    }

    fprintf(stderr, "start=%lld\n", start_time);

    if (start_time != MAXINT64)

        ic->start_time = start_time;

    /* estimate the end time (duration) */

    /* XXX: may need to support wrapping */

    filesize = ic->file_size;

    offset = filesize - DURATION_MAX_READ_SIZE;

    if (offset < 0)

        offset = 0;

    /* flush packet queue */

    flush_packet_queue(ic);

    url_fseek(&ic->pb, offset, SEEK_SET);

    read_size = 0;

    for(;;) {

        if (read_size >= DURATION_MAX_READ_SIZE)

            break;

        /* if all info is available, we can stop */

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

            st = ic->streams[i];

            if (st->duration == AV_NOPTS_VALUE)

                break;

        }

        if (i == ic->nb_streams)

            break;

        ret = av_read_packet(ic, pkt);

        if (ret != 0)

            break;

        read_size += pkt->size;

        st = ic->streams[pkt->stream_index];

        if (pkt->pts != AV_NOPTS_VALUE) {

            end_time = (int64_t)((double)pkt->pts * ic->pts_num * (double)AV_TIME_BASE / ic->pts_den);

            duration = end_time - st->start_time;

            if (duration > 0) {

                if (st->duration == AV_NOPTS_VALUE ||

                    st->duration < duration)

                    st->duration = duration;

            }

        }

        av_free_packet(pkt);

    }

    /* estimate total duration */

    end_time = MININT64;

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

        st = ic->streams[i];

        if (st->duration != AV_NOPTS_VALUE) {

            end_time1 = st->start_time + st->duration;

            if (end_time1 > end_time)

                end_time = end_time1;

        }

    }

    /* update start_time (new stream may have been created, so we do

       it at the end */

    if (ic->start_time != AV_NOPTS_VALUE) {

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

            st = ic->streams[i];

            if (st->start_time == AV_NOPTS_VALUE)

                st->start_time = ic->start_time;

        }

    }

    if (end_time != MININT64) {

        /* put dummy values for duration if needed */

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

            st = ic->streams[i];

            if (st->duration == AV_NOPTS_VALUE &&

                st->start_time != AV_NOPTS_VALUE)

                st->duration = end_time - st->start_time;

        }

        ic->duration = end_time - ic->start_time;

    }

    url_fseek(&ic->pb, 0, SEEK_SET);

}


bool qemu_clock_run_all_timers(void)

{

    bool progress = false;

    QEMUClockType type;

    for (type = 0; type < QEMU_CLOCK_MAX; type++) {

        progress |= qemu_clock_run_timers(type);

    }

    return progress;

}


static int put_uint64_as_uint32(QEMUFile *f, void *pv, size_t size,

                                VMStateField *field, QJSON *vmdesc)

{

    uint64_t *v = pv;

    qemu_put_be32(f, *v);

    return 0;

}


static void scsi_dma_restart_bh(void *opaque)

{

    SCSIDevice *s = opaque;

    SCSIRequest *req, *next;

    qemu_bh_delete(s->bh);

    s->bh = NULL;

    QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) {

        scsi_req_ref(req);

        if (req->retry) {

            req->retry = false;

            switch (req->cmd.mode) {

            case SCSI_XFER_FROM_DEV:

            case SCSI_XFER_TO_DEV:

                scsi_req_continue(req);

                break;

            case SCSI_XFER_NONE:

                assert(!req->sg);

                scsi_req_dequeue(req);

                scsi_req_enqueue(req);

                break;

            }

        }

        scsi_req_unref(req);

    }

}


static uint64_t get_guest_rtc_ns(RTCState *s)

{

    uint64_t guest_rtc;

    uint64_t guest_clock = qemu_clock_get_ns(rtc_clock);

    guest_rtc = s->base_rtc * NANOSECONDS_PER_SECOND +

        guest_clock - s->last_update + s->offset;

    return guest_rtc;

}


static void openpic_reset(DeviceState *d)

{

    OpenPICState *opp = FROM_SYSBUS(typeof (*opp), sysbus_from_qdev(d));

    int i;

    opp->glbc = GLBC_RESET;

    /* Initialise controller registers */

    opp->frep = ((opp->nb_irqs -1) << FREP_NIRQ_SHIFT) |

                ((opp->nb_cpus -1) << FREP_NCPU_SHIFT) |

                (opp->vid << FREP_VID_SHIFT);

    opp->pint = 0;

    opp->spve = -1 & opp->spve_mask;

    opp->tifr = opp->tifr_reset;

    /* Initialise IRQ sources */

    for (i = 0; i < opp->max_irq; i++) {

        opp->src[i].ipvp = opp->ipvp_reset;

        opp->src[i].ide  = opp->ide_reset;

    }

    /* Initialise IRQ destinations */

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

        opp->dst[i].pctp      = 15;

        opp->dst[i].pcsr      = 0x00000000;

        memset(&opp->dst[i].raised, 0, sizeof(IRQ_queue_t));

        opp->dst[i].raised.next = -1;

        memset(&opp->dst[i].servicing, 0, sizeof(IRQ_queue_t));

        opp->dst[i].servicing.next = -1;

    }

    /* Initialise timers */

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

        opp->timers[i].ticc = 0;

        opp->timers[i].tibc = TIBC_CI;

    }

    /* Go out of RESET state */

    opp->glbc = 0;

}


static inline int handle_cpu_signal(unsigned long pc, unsigned long address,

                                    int is_write, sigset_t *old_set,

                                    void *puc)

{

    TranslationBlock *tb;

    int ret;

    if (cpu_single_env)

        env = cpu_single_env; /* XXX: find a correct solution for multithread */

#if defined(DEBUG_SIGNAL)

    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",

           pc, address, is_write, *(unsigned long *)old_set);

#endif

    /* XXX: locking issue */

    if (is_write && page_unprotect(h2g(address), pc, puc)) {

        return 1;

    }

    /* see if it is an MMU fault */

    ret = cpu_mb_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);

    if (ret < 0)

        return 0; /* not an MMU fault */

    if (ret == 0)

        return 1; /* the MMU fault was handled without causing real CPU fault */

    /* now we have a real cpu fault */

    tb = tb_find_pc(pc);

    if (tb) {

        /* the PC is inside the translated code. It means that we have

           a virtual CPU fault */

        cpu_restore_state(tb, env, pc, puc);

    }

    if (ret == 1) {

#if 0

        printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n",

               env->PC, env->error_code, tb);

#endif

    /* we restore the process signal mask as the sigreturn should

       do it (XXX: use sigsetjmp) */

        sigprocmask(SIG_SETMASK, old_set, NULL);

        cpu_loop_exit();

    } else {

        /* activate soft MMU for this block */

        cpu_resume_from_signal(env, puc);

    }

    /* never comes here */

    return 1;

}


static int scan_mmco_reset(AVCodecParserContext *s, GetBitContext *gb)

{

    H264PredWeightTable pwt;

    int slice_type_nos = s->pict_type & 3;

    H264ParseContext *p = s->priv_data;

    H264Context      *h = &p->h;

    int list_count, ref_count[2];

    if (h->pps.redundant_pic_cnt_present)

        get_ue_golomb(gb); // redundant_pic_count

    if (slice_type_nos == AV_PICTURE_TYPE_B)

        get_bits1(gb); // direct_spatial_mv_pred

    if (ff_h264_parse_ref_count(&list_count, ref_count, gb, &h->pps,

                                slice_type_nos, h->picture_structure) < 0)

        return AVERROR_INVALIDDATA;

    if (slice_type_nos != AV_PICTURE_TYPE_I) {

        int list;

        for (list = 0; list < list_count; list++) {

            if (get_bits1(gb)) {

                int index;

                for (index = 0; ; index++) {

                    unsigned int reordering_of_pic_nums_idc = get_ue_golomb_31(gb);

                    if (reordering_of_pic_nums_idc < 3)

                        get_ue_golomb(gb);

                    else if (reordering_of_pic_nums_idc > 3) {

                        av_log(h->avctx, AV_LOG_ERROR,

                               "illegal reordering_of_pic_nums_idc %d\n",

                               reordering_of_pic_nums_idc);

                        return AVERROR_INVALIDDATA;

                    } else

                        break;

                    if (index >= ref_count[list]) {

                        av_log(h->avctx, AV_LOG_ERROR,

                               "reference count %d overflow\n", index);

                        return AVERROR_INVALIDDATA;

                    }

                }

            }

        }

    }

    if ((h->pps.weighted_pred && slice_type_nos == AV_PICTURE_TYPE_P) ||

        (h->pps.weighted_bipred_idc == 1 && slice_type_nos == AV_PICTURE_TYPE_B))

        ff_h264_pred_weight_table(gb, &h->sps, ref_count, slice_type_nos,

                                  &pwt);

    if (get_bits1(gb)) { // adaptive_ref_pic_marking_mode_flag

        int i;

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

            MMCOOpcode opcode = get_ue_golomb_31(gb);

            if (opcode > (unsigned) MMCO_LONG) {

                av_log(h->avctx, AV_LOG_ERROR,

                       "illegal memory management control operation %d\n",

                       opcode);

                return AVERROR_INVALIDDATA;

            }

            if (opcode == MMCO_END)

               return 0;

            else if (opcode == MMCO_RESET)

                return 1;

            if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG)

                get_ue_golomb(gb);

            if (opcode == MMCO_SHORT2LONG || opcode == MMCO_LONG2UNUSED ||

                opcode == MMCO_LONG || opcode == MMCO_SET_MAX_LONG)

                get_ue_golomb_31(gb);

        }

    }

    return 0;

}


void helper_memalign(uint32_t addr, uint32_t dr, uint32_t wr, uint32_t size)

{

    uint32_t mask;

    switch (size) {

        case 4: mask = 3; break;

        case 2: mask = 1; break;

        default:

        case 1: mask = 0; break;

    }

    if (addr & mask) {

            qemu_log("unaligned access addr=%x size=%d, wr=%d\n",

                     addr, size, wr);

            if (!(env->sregs[SR_MSR] & MSR_EE)) {

                return;

            }

            env->sregs[SR_ESR] = ESR_EC_UNALIGNED_DATA | (wr << 10) \

                                 | (dr & 31) << 5;

            if (size == 4) {

                env->sregs[SR_ESR] |= 1 << 11;

            }

            helper_raise_exception(EXCP_HW_EXCP);

    }

}


static inline bool bdrv_req_is_aligned(BlockDriverState *bs,

                                       int64_t offset, size_t bytes)

{

    int64_t align = bdrv_get_align(bs);

    return !(offset & (align - 1) || (bytes & (align - 1)));

}


static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,

                                      long search_pc)

{

    int opc, op_index, macro_op_index;

    const TCGOpDef *def;

    unsigned int dead_iargs;

    const TCGArg *args;

#ifdef DEBUG_DISAS

    if (unlikely(loglevel & CPU_LOG_TB_OP)) {

        fprintf(logfile, "OP:\n");

        tcg_dump_ops(s, logfile);

        fprintf(logfile, "\n");

    }

#endif

    tcg_liveness_analysis(s);

#ifdef DEBUG_DISAS

    if (unlikely(loglevel & CPU_LOG_TB_OP_OPT)) {

        fprintf(logfile, "OP after la:\n");

        tcg_dump_ops(s, logfile);

        fprintf(logfile, "\n");

    }

#endif

    tcg_reg_alloc_start(s);

    s->code_buf = gen_code_buf;

    s->code_ptr = gen_code_buf;

    macro_op_index = -1;

    args = gen_opparam_buf;

    op_index = 0;

    for(;;) {

        opc = gen_opc_buf[op_index];

#ifdef CONFIG_PROFILER

        dyngen_table_op_count[opc]++;

#endif

        def = &tcg_op_defs[opc];

#if 0

        printf("%s: %d %d %d\n", def->name,

               def->nb_oargs, def->nb_iargs, def->nb_cargs);

        //        dump_regs(s);

#endif

        switch(opc) {

        case INDEX_op_mov_i32:

#if TCG_TARGET_REG_BITS == 64

        case INDEX_op_mov_i64:

#endif

            dead_iargs = s->op_dead_iargs[op_index];

            tcg_reg_alloc_mov(s, def, args, dead_iargs);

            break;

        case INDEX_op_nop:

        case INDEX_op_nop1:

        case INDEX_op_nop2:

        case INDEX_op_nop3:

            break;

        case INDEX_op_nopn:

            args += args[0];

            goto next;

        case INDEX_op_discard:

            {

                TCGTemp *ts;

                ts = &s->temps[args[0]];

                /* mark the temporary as dead */

                if (ts->val_type != TEMP_VAL_CONST && !ts->fixed_reg) {

                    if (ts->val_type == TEMP_VAL_REG)

                        s->reg_to_temp[ts->reg] = -1;

                    ts->val_type = TEMP_VAL_DEAD;

                }

            }

            break;

        case INDEX_op_macro_goto:

            macro_op_index = op_index; /* only used for exceptions */

            op_index = args[0] - 1;

            args = gen_opparam_buf + args[1];

            goto next;

        case INDEX_op_macro_end:

            macro_op_index = -1; /* only used for exceptions */

            op_index = args[0] - 1;

            args = gen_opparam_buf + args[1];

            goto next;

        case INDEX_op_macro_start:

            /* must never happen here */

            tcg_abort();

        case INDEX_op_set_label:

            tcg_reg_alloc_bb_end(s);

            tcg_out_label(s, args[0], (long)s->code_ptr);

            break;

        case INDEX_op_call:

            dead_iargs = s->op_dead_iargs[op_index];

            args += tcg_reg_alloc_call(s, def, opc, args, dead_iargs);

            goto next;

        case INDEX_op_end:

            goto the_end;

#ifndef CONFIG_NO_DYNGEN_OP

        case 0 ... INDEX_op_end - 1:

            /* legacy dyngen ops */

#ifdef CONFIG_PROFILER

            {

                extern int64_t dyngen_old_op_count;

                dyngen_old_op_count++;

            }

#endif

            tcg_reg_alloc_bb_end(s);

            if (search_pc >= 0) {

                s->code_ptr += def->copy_size;

                args += def->nb_args;

            } else {

                args = dyngen_op(s, opc, args);

            }

            goto next;

#endif

        default:

            /* Note: in order to speed up the code, it would be much

               faster to have specialized register allocator functions for

               some common argument patterns */

            dead_iargs = s->op_dead_iargs[op_index];

            tcg_reg_alloc_op(s, def, opc, args, dead_iargs);

            break;

        }

        args += def->nb_args;

    next: ;

        if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {

            if (macro_op_index >= 0)

                return macro_op_index;

            else

                return op_index;

        }

        op_index++;

#ifndef NDEBUG

        check_regs(s);

#endif

    }

 the_end:

    return -1;

}


static uint32_t set_isolation_state(sPAPRDRConnector *drc,

                                    sPAPRDRIsolationState state)

{

    trace_spapr_drc_set_isolation_state(spapr_drc_index(drc), state);

    /* if the guest is configuring a device attached to this DRC, we

     * should reset the configuration state at this point since it may

     * no longer be reliable (guest released device and needs to start

     * over, or unplug occurred so the FDT is no longer valid)

     */

    if (state == SPAPR_DR_ISOLATION_STATE_ISOLATED) {

        g_free(drc->ccs);

        drc->ccs = NULL;

    }

    if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) {

        /* cannot unisolate a non-existent resource, and, or resources

         * which are in an 'UNUSABLE' allocation state. (PAPR 2.7, 13.5.3.5)

         */

        if (!drc->dev ||

            drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {

            return RTAS_OUT_NO_SUCH_INDICATOR;

        }

    }

    /*

     * Fail any requests to ISOLATE the LMB DRC if this LMB doesn't

     * belong to a DIMM device that is marked for removal.

     *

     * Currently the guest userspace tool drmgr that drives the memory

     * hotplug/unplug will just try to remove a set of 'removable' LMBs

     * in response to a hot unplug request that is based on drc-count.

     * If the LMB being removed doesn't belong to a DIMM device that is

     * actually being unplugged, fail the isolation request here.

     */

    if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB) {

        if ((state == SPAPR_DR_ISOLATION_STATE_ISOLATED) &&

             !drc->awaiting_release) {

            return RTAS_OUT_HW_ERROR;

        }

    }

    drc->isolation_state = state;

    if (drc->isolation_state == SPAPR_DR_ISOLATION_STATE_ISOLATED) {

        /* if we're awaiting release, but still in an unconfigured state,

         * it's likely the guest is still in the process of configuring

         * the device and is transitioning the devices to an ISOLATED

         * state as a part of that process. so we only complete the

         * removal when this transition happens for a device in a

         * configured state, as suggested by the state diagram from

         * PAPR+ 2.7, 13.4

         */

        if (drc->awaiting_release) {

            uint32_t drc_index = spapr_drc_index(drc);

            if (drc->configured) {

                trace_spapr_drc_set_isolation_state_finalizing(drc_index);

                spapr_drc_detach(drc, DEVICE(drc->dev), NULL);

            } else {

                trace_spapr_drc_set_isolation_state_deferring(drc_index);

            }

        }

        drc->configured = false;

    }

    return RTAS_OUT_SUCCESS;

}


static void vnc_listen_read(void *opaque)

{

    VncDisplay *vs = opaque;

    struct sockaddr_in addr;

    socklen_t addrlen = sizeof(addr);

    /* Catch-up */

    vga_hw_update();

    int csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);

    if (csock != -1) {

        vnc_connect(vs, csock);

    }

}


static av_cold int qdm2_decode_init(AVCodecContext *avctx)

{

    QDM2Context *s = avctx->priv_data;

    uint8_t *extradata;

    int extradata_size;

    int tmp_val, tmp, size;

    /* extradata parsing

    Structure:

    wave {

        frma (QDM2)

        QDCA

        QDCP

    }

    32  size (including this field)

    32  tag (=frma)

    32  type (=QDM2 or QDMC)

    32  size (including this field, in bytes)

    32  tag (=QDCA) // maybe mandatory parameters

    32  unknown (=1)

    32  channels (=2)

    32  samplerate (=44100)

    32  bitrate (=96000)

    32  block size (=4096)

    32  frame size (=256) (for one channel)

    32  packet size (=1300)

    32  size (including this field, in bytes)

    32  tag (=QDCP) // maybe some tuneable parameters

    32  float1 (=1.0)

    32  zero ?

    32  float2 (=1.0)

    32  float3 (=1.0)

    32  unknown (27)

    32  unknown (8)

    32  zero ?

    */

    if (!avctx->extradata || (avctx->extradata_size < 48)) {

        av_log(avctx, AV_LOG_ERROR, "extradata missing or truncated\n");

        return -1;

    }

    extradata = avctx->extradata;

    extradata_size = avctx->extradata_size;

    while (extradata_size > 7) {

        if (!memcmp(extradata, "frmaQDM", 7))

            break;

        extradata++;

        extradata_size--;

    }

    if (extradata_size < 12) {

        av_log(avctx, AV_LOG_ERROR, "not enough extradata (%i)\n",

               extradata_size);

        return -1;

    }

    if (memcmp(extradata, "frmaQDM", 7)) {

        av_log(avctx, AV_LOG_ERROR, "invalid headers, QDM? not found\n");

        return -1;

    }

    if (extradata[7] == 'C') {

//        s->is_qdmc = 1;

        av_log(avctx, AV_LOG_ERROR, "stream is QDMC version 1, which is not supported\n");

        return -1;

    }

    extradata += 8;

    extradata_size -= 8;

    size = AV_RB32(extradata);

    if(size > extradata_size){

        av_log(avctx, AV_LOG_ERROR, "extradata size too small, %i < %i\n",

               extradata_size, size);

        return -1;

    }

    extradata += 4;

    av_log(avctx, AV_LOG_DEBUG, "size: %d\n", size);

    if (AV_RB32(extradata) != MKBETAG('Q','D','C','A')) {

        av_log(avctx, AV_LOG_ERROR, "invalid extradata, expecting QDCA\n");

        return -1;

    }

    extradata += 8;

    avctx->channels = s->nb_channels = s->channels = AV_RB32(extradata);

    extradata += 4;

    if (s->channels > MPA_MAX_CHANNELS)

        return AVERROR_INVALIDDATA;

    avctx->sample_rate = AV_RB32(extradata);

    extradata += 4;

    avctx->bit_rate = AV_RB32(extradata);

    extradata += 4;

    s->group_size = AV_RB32(extradata);

    extradata += 4;

    s->fft_size = AV_RB32(extradata);

    extradata += 4;

    s->checksum_size = AV_RB32(extradata);

    if (s->checksum_size >= 1U << 28) {

        av_log(avctx, AV_LOG_ERROR, "data block size too large (%u)\n", s->checksum_size);

        return AVERROR_INVALIDDATA;

    }

    s->fft_order = av_log2(s->fft_size) + 1;

    s->fft_frame_size = 2 * s->fft_size; // complex has two floats

    // something like max decodable tones

    s->group_order = av_log2(s->group_size) + 1;

    s->frame_size = s->group_size / 16; // 16 iterations per super block

    if (s->frame_size > QDM2_MAX_FRAME_SIZE)

        return AVERROR_INVALIDDATA;

    s->sub_sampling = s->fft_order - 7;

    s->frequency_range = 255 / (1 << (2 - s->sub_sampling));

    switch ((s->sub_sampling * 2 + s->channels - 1)) {

        case 0: tmp = 40; break;

        case 1: tmp = 48; break;

        case 2: tmp = 56; break;

        case 3: tmp = 72; break;

        case 4: tmp = 80; break;

        case 5: tmp = 100;break;

        default: tmp=s->sub_sampling; break;

    }

    tmp_val = 0;

    if ((tmp * 1000) < avctx->bit_rate)  tmp_val = 1;

    if ((tmp * 1440) < avctx->bit_rate)  tmp_val = 2;

    if ((tmp * 1760) < avctx->bit_rate)  tmp_val = 3;

    if ((tmp * 2240) < avctx->bit_rate)  tmp_val = 4;

    s->cm_table_select = tmp_val;

    if (s->sub_sampling == 0)

        tmp = 7999;

    else

        tmp = ((-(s->sub_sampling -1)) & 8000) + 20000;

    /*

    0: 7999 -> 0

    1: 20000 -> 2

    2: 28000 -> 2

    */

    if (tmp < 8000)

        s->coeff_per_sb_select = 0;

    else if (tmp <= 16000)

        s->coeff_per_sb_select = 1;

    else

        s->coeff_per_sb_select = 2;

    // Fail on unknown fft order

    if ((s->fft_order < 7) || (s->fft_order > 9)) {

        av_log(avctx, AV_LOG_ERROR, "Unknown FFT order (%d), contact the developers!\n", s->fft_order);

        return -1;

    }

    ff_rdft_init(&s->rdft_ctx, s->fft_order, IDFT_C2R);

    ff_mpadsp_init(&s->mpadsp);

    qdm2_init(s);

    avctx->sample_fmt = AV_SAMPLE_FMT_S16;

    avcodec_get_frame_defaults(&s->frame);

    avctx->coded_frame = &s->frame;

//    dump_context(s);

    return 0;

}


void MPV_frame_end(MpegEncContext *s)

{

    /* draw edge for correct motion prediction if outside */

    if (s->pict_type != B_TYPE && !s->intra_only) {

      if(s->avctx==NULL || s->avctx->codec->id!=CODEC_ID_MPEG4 || s->divx_version==500){

        draw_edges(s->current_picture[0], s->linesize, s->mb_width*16, s->mb_height*16, EDGE_WIDTH);

        draw_edges(s->current_picture[1], s->linesize/2, s->mb_width*8, s->mb_height*8, EDGE_WIDTH/2);

        draw_edges(s->current_picture[2], s->linesize/2, s->mb_width*8, s->mb_height*8, EDGE_WIDTH/2);

      }else{

        /* mpeg4? / opendivx / xvid */

        draw_edges(s->current_picture[0], s->linesize, s->width, s->height, EDGE_WIDTH);

        draw_edges(s->current_picture[1], s->linesize/2, s->width/2, s->height/2, EDGE_WIDTH/2);

        draw_edges(s->current_picture[2], s->linesize/2, s->width/2, s->height/2, EDGE_WIDTH/2);

      }

    }

    emms_c();

    if(s->pict_type!=B_TYPE){

        s->last_non_b_pict_type= s->pict_type;

        s->last_non_b_qscale= s->qscale;

        s->last_non_b_mc_mb_var= s->mc_mb_var;

        s->num_available_buffers++;

        if(s->num_available_buffers>2) s->num_available_buffers= 2;

    }

}


void qmp_memchar_write(const char *device, int64_t size,

                       const char *data, bool has_format,

                       enum DataFormat format,

                       Error **errp)

{

    CharDriverState *chr;

    guchar *write_data;

    int ret;

    gsize write_count;

    chr = qemu_chr_find(device);

    if (!chr) {

        error_set(errp, QERR_DEVICE_NOT_FOUND, device);

        return;

    }

    if (qemu_is_chr(chr, "memory")) {

        error_setg(errp,"%s is not memory char device", device);

        return;

    }

    write_count = (gsize)size;

    if (has_format && (format == DATA_FORMAT_BASE64)) {

        write_data = g_base64_decode(data, &write_count);

    } else {

        write_data = (uint8_t *)data;

    }

    ret = cirmem_chr_write(chr, write_data, write_count);

    if (ret < 0) {

        error_setg(errp, "Failed to write to device %s", device);

        return;

    }

}


kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )

{

    io_object_t     nextMedia;

    kern_return_t   kernResult = KERN_FAILURE;

    *bsdPath = '\0';

    nextMedia = IOIteratorNext( mediaIterator );

    if ( nextMedia )

    {

        CFTypeRef   bsdPathAsCFString;

    bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );

        if ( bsdPathAsCFString ) {

            size_t devPathLength;

            strcpy( bsdPath, _PATH_DEV );

            strcat( bsdPath, "r" );

            devPathLength = strlen( bsdPath );

            if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {

                kernResult = KERN_SUCCESS;

            }

            CFRelease( bsdPathAsCFString );

        }

        IOObjectRelease( nextMedia );

    }

    return kernResult;

}


static void host_x86_cpu_class_init(ObjectClass *oc, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(oc);

    X86CPUClass *xcc = X86_CPU_CLASS(oc);

    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;

    xcc->kvm_required = true;

    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);

    x86_cpu_vendor_words2str(host_cpudef.vendor, ebx, edx, ecx);

    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);

    host_cpudef.family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);

    host_cpudef.model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);

    host_cpudef.stepping = eax & 0x0F;

    cpu_x86_fill_model_id(host_cpudef.model_id);

    xcc->cpu_def = &host_cpudef;

    host_cpudef.cache_info_passthrough = true;

    /* level, xlevel, xlevel2, and the feature words are initialized on

     * instance_init, because they require KVM to be initialized.

     */

    dc->props = host_x86_cpu_properties;

}


int ff_http_do_new_request(URLContext *h, const char *uri)
{
    HTTPContext *s = h->priv_data;
    AVDictionary *options = NULL;
    int ret;
    ret = http_shutdown(h, h->flags);
    if (ret < 0)
        return ret;
    s->end_chunked_post = 0;
    s->chunkend      = 0;
    s->off           = 0;
    s->icy_data_read = 0;
    av_free(s->location);
    s->location = av_strdup(uri);
    if (!s->location)
        return AVERROR(ENOMEM);
    ret = http_open_cnx(h, &options);
    av_dict_free(&options);
    return ret;


uint_fast16_t float32_to_uint16_round_to_zero(float32 a STATUS_PARAM)

{

    int64_t v;

    uint_fast16_t res;

    v = float32_to_int64_round_to_zero(a STATUS_VAR);

    if (v < 0) {

        res = 0;

        float_raise( float_flag_invalid STATUS_VAR);

    } else if (v > 0xffff) {

        res = 0xffff;

        float_raise( float_flag_invalid STATUS_VAR);

    } else {

        res = v;

    }

    return res;

}


static int hda_codec_dev_init(DeviceState *qdev, DeviceInfo *base)

{

    HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, qdev->parent_bus);

    HDACodecDevice *dev = DO_UPCAST(HDACodecDevice, qdev, qdev);

    HDACodecDeviceInfo *info = DO_UPCAST(HDACodecDeviceInfo, qdev, base);

    dev->info = info;

    if (dev->cad == -1) {

        dev->cad = bus->next_cad;

    }

    if (dev->cad > 15)

        return -1;

    bus->next_cad = dev->cad + 1;

    return info->init(dev);

}


static void setup_frame_v1(int usig, struct target_sigaction *ka,

                           target_sigset_t *set, CPUARMState *regs)

{

	struct sigframe_v1 *frame;

	abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));

	int i;

	if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))

		return;

	setup_sigcontext(&frame->sc, regs, set->sig[0]);

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

            if (__put_user(set->sig[i], &frame->extramask[i - 1]))

                goto end;

	}

        setup_return(regs, ka, &frame->retcode, frame_addr, usig,

                     frame_addr + offsetof(struct sigframe_v1, retcode));

end:

	unlock_user_struct(frame, frame_addr, 1);

}


qcrypto_tls_creds_x509_init(Object *obj)
{
    object_property_add_bool(obj, "loaded",
                             qcrypto_tls_creds_x509_prop_get_loaded,
                             qcrypto_tls_creds_x509_prop_set_loaded,
}


int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,

    int n_start, int n_end, int *num, uint64_t *host_offset, QCowL2Meta **m)

{

    BDRVQcowState *s = bs->opaque;

    uint64_t start, remaining;

    uint64_t cluster_offset;

    uint64_t cur_bytes;

    int ret;

    trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), offset,

                                      n_start, n_end);

    assert(n_start * BDRV_SECTOR_SIZE == offset_into_cluster(s, offset));

    offset = start_of_cluster(s, offset);

again:

    start = offset + (n_start << BDRV_SECTOR_BITS);

    remaining = (n_end - n_start) << BDRV_SECTOR_BITS;

    cluster_offset = 0;

    *host_offset = 0;

    while (true) {

        /*

         * Now start gathering as many contiguous clusters as possible:

         *

         * 1. Check for overlaps with in-flight allocations

         *

         *      a) Overlap not in the first cluster -> shorten this request and

         *         let the caller handle the rest in its next loop iteration.

         *

         *      b) Real overlaps of two requests. Yield and restart the search

         *         for contiguous clusters (the situation could have changed

         *         while we were sleeping)

         *

         *      c) TODO: Request starts in the same cluster as the in-flight

         *         allocation ends. Shorten the COW of the in-fight allocation,

         *         set cluster_offset to write to the same cluster and set up

         *         the right synchronisation between the in-flight request and

         *         the new one.

         */

        cur_bytes = remaining;

        ret = handle_dependencies(bs, start, &cur_bytes);

        if (ret == -EAGAIN) {

            goto again;

        } else if (ret < 0) {

            return ret;

        } else {

            /* handle_dependencies() may have decreased cur_bytes (shortened

             * the allocations below) so that the next dependency is processed

             * correctly during the next loop iteration. */

        }

        /*

         * 2. Count contiguous COPIED clusters.

         */

        ret = handle_copied(bs, start, &cluster_offset, &cur_bytes, m);

        if (ret < 0) {

            return ret;

        } else if (ret) {

            if (!*host_offset) {

                *host_offset = start_of_cluster(s, cluster_offset);

            }

            start           += cur_bytes;

            remaining       -= cur_bytes;

            cluster_offset  += cur_bytes;

            cur_bytes = remaining;

        } else if (cur_bytes == 0) {

            break;

        }

        /* If there is something left to allocate, do that now */

        if (remaining == 0) {

            break;

        }

        /*

         * 3. If the request still hasn't completed, allocate new clusters,

         *    considering any cluster_offset of steps 1c or 2.

         */

        ret = handle_alloc(bs, start, &cluster_offset, &cur_bytes, m);

        if (ret < 0) {

            return ret;

        } else if (ret) {

            if (!*host_offset) {

                *host_offset = start_of_cluster(s, cluster_offset);

            }

            start           += cur_bytes;

            remaining       -= cur_bytes;

            cluster_offset  += cur_bytes;

            break;

        } else {

            assert(cur_bytes == 0);

            break;

        }

    }

    *num = (n_end - n_start) - (remaining >> BDRV_SECTOR_BITS);

    assert(*num > 0);

    assert(*host_offset != 0);

    return 0;

}


static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int flags)

{

    PerThreadContext *p = avctx->thread_opaque;

    int err;

    f->owner = avctx;

    ff_init_buffer_info(avctx, f->f);

    if (!(avctx->active_thread_type & FF_THREAD_FRAME))

        return ff_get_buffer(avctx, f->f, flags);

    if (p->state != STATE_SETTING_UP &&

        (avctx->codec->update_thread_context || (!avctx->thread_safe_callbacks &&

                avctx->get_buffer != avcodec_default_get_buffer))) {

        av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n");

        return -1;

    }

    if (avctx->internal->allocate_progress) {

        int *progress;

        f->progress = av_buffer_alloc(2 * sizeof(int));

        if (!f->progress) {

            return AVERROR(ENOMEM);

        }

        progress = (int*)f->progress->data;

        progress[0] = progress[1] = -1;

    }

    pthread_mutex_lock(&p->parent->buffer_mutex);

    if (avctx->thread_safe_callbacks || (

#if FF_API_GET_BUFFER

        !avctx->get_buffer &&

#endif

        avctx->get_buffer2 == avcodec_default_get_buffer2)) {

        err = ff_get_buffer(avctx, f->f, flags);

    } else {

        pthread_mutex_lock(&p->progress_mutex);

        p->requested_frame = f->f;

        p->requested_flags = flags;

        p->state = STATE_GET_BUFFER;

        pthread_cond_broadcast(&p->progress_cond);

        while (p->state != STATE_SETTING_UP)

            pthread_cond_wait(&p->progress_cond, &p->progress_mutex);

        err = p->result;

        pthread_mutex_unlock(&p->progress_mutex);

        if (!avctx->codec->update_thread_context)

            ff_thread_finish_setup(avctx);

    }

    if (err)

        av_buffer_unref(&f->progress);

    pthread_mutex_unlock(&p->parent->buffer_mutex);

    return err;

}


static void xio3130_downstream_realize(PCIDevice *d, Error **errp)

{

    PCIEPort *p = PCIE_PORT(d);

    PCIESlot *s = PCIE_SLOT(d);

    int rc;

    pci_bridge_initfn(d, TYPE_PCIE_BUS);

    pcie_port_init_reg(d);

    rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR,

                  XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,

                  XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT,

                  errp);

    if (rc < 0) {

        assert(rc == -ENOTSUP);

        goto err_bridge;

    }

    rc = pci_bridge_ssvid_init(d, XIO3130_SSVID_OFFSET,

                               XIO3130_SSVID_SVID, XIO3130_SSVID_SSID,

                               errp);

    if (rc < 0) {

        goto err_bridge;

    }

    rc = pcie_cap_init(d, XIO3130_EXP_OFFSET, PCI_EXP_TYPE_DOWNSTREAM,

                       p->port, errp);

    if (rc < 0) {

        goto err_msi;

    }

    pcie_cap_flr_init(d);

    pcie_cap_deverr_init(d);

    pcie_cap_slot_init(d, s->slot);

    pcie_cap_arifwd_init(d);

    pcie_chassis_create(s->chassis);

    rc = pcie_chassis_add_slot(s);

    if (rc < 0) {

        goto err_pcie_cap;

    }

    rc = pcie_aer_init(d, PCI_ERR_VER, XIO3130_AER_OFFSET,

                       PCI_ERR_SIZEOF, errp);

    if (rc < 0) {

        goto err;

    }

    return;

err:

    pcie_chassis_del_slot(s);

err_pcie_cap:

    pcie_cap_exit(d);

err_msi:

    msi_uninit(d);

err_bridge:

    pci_bridge_exitfn(d);

}


static int qcow_write(BlockDriverState *bs, int64_t sector_num,

                     const uint8_t *buf, int nb_sectors)

{

    BDRVQcowState *s = bs->opaque;

    int ret, index_in_cluster, n;

    uint64_t cluster_offset;

    int n_end;

    while (nb_sectors > 0) {

        index_in_cluster = sector_num & (s->cluster_sectors - 1);

        n_end = index_in_cluster + nb_sectors;

        if (s->crypt_method &&

            n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors)

            n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors;

        cluster_offset = alloc_cluster_offset(bs, sector_num << 9,

                                              index_in_cluster,

                                              n_end, &n);

        if (!cluster_offset)

            return -1;

        if (s->crypt_method) {

            encrypt_sectors(s, sector_num, s->cluster_data, buf, n, 1,

                            &s->aes_encrypt_key);

            ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512,

                              s->cluster_data, n * 512);

        } else {

            ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);

        }

        if (ret != n * 512)

            return -1;

        nb_sectors -= n;

        sector_num += n;

        buf += n * 512;

    }

    s->cluster_cache_offset = -1; /* disable compressed cache */

    return 0;

}


static void vnc_dpy_resize(DisplayState *ds)

{

    int size_changed;

    VncState *vs = ds->opaque;

    vs->old_data = qemu_realloc(vs->old_data, ds_get_linesize(ds) * ds_get_height(ds));

    if (vs->old_data == NULL) {

	fprintf(stderr, "vnc: memory allocation failed\n");

	exit(1);

    }

    if (ds_get_bytes_per_pixel(ds) != vs->depth)

        console_color_init(ds);

    vnc_colordepth(ds);

    size_changed = ds_get_width(ds) != vs->width || ds_get_height(ds) != vs->height;

    if (size_changed) {

        vs->width = ds_get_width(ds);

        vs->height = ds_get_height(ds);

        if (vs->csock != -1 && vs->has_resize) {

            vnc_write_u8(vs, 0);  /* msg id */

            vnc_write_u8(vs, 0);

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

            vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds), -223);

            vnc_flush(vs);

        }

    }

    memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));

    memset(vs->old_data, 42, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));

}


static inline int cris_bound_b(int v, int b)

{

	int r = v;

	asm ("bound.b\t%1, %0\n" : "+r" (r) : "ri" (b));

	return r;

}


static int virtio_ccw_hcall_notify(const uint64_t *args)

{

    uint64_t subch_id = args[0];

    uint64_t queue = args[1];

    SubchDev *sch;

    int cssid, ssid, schid, m;

    if (ioinst_disassemble_sch_ident(subch_id, &m, &cssid, &ssid, &schid)) {

    sch = css_find_subch(m, cssid, ssid, schid);

    if (!sch || !css_subch_visible(sch)) {

    virtio_queue_notify(virtio_ccw_get_vdev(sch), queue);

    return 0;


static int dirac_decode_frame_internal(DiracContext *s)

{

    DWTContext d;

    int y, i, comp, dsty;

    int ret;

    if (s->low_delay) {

        /* [DIRAC_STD] 13.5.1 low_delay_transform_data() */

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

            Plane *p = &s->plane[comp];

            memset(p->idwt_buf, 0, p->idwt_stride * p->idwt_height * sizeof(IDWTELEM));

        }

        if (!s->zero_res) {

            if ((ret = decode_lowdelay(s)) < 0)

                return ret;

        }

    }

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

        Plane *p       = &s->plane[comp];

        uint8_t *frame = s->current_picture->avframe->data[comp];

        /* FIXME: small resolutions */

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

            s->edge_emu_buffer[i] = s->edge_emu_buffer_base + i*FFALIGN(p->width, 16);

        if (!s->zero_res && !s->low_delay)

        {

            memset(p->idwt_buf, 0, p->idwt_stride * p->idwt_height * sizeof(IDWTELEM));

            decode_component(s, comp); /* [DIRAC_STD] 13.4.1 core_transform_data() */

        }

        ret = ff_spatial_idwt_init2(&d, p->idwt_buf, p->idwt_width, p->idwt_height, p->idwt_stride,

                                    s->wavelet_idx+2, s->wavelet_depth, p->idwt_tmp);

        if (ret < 0)

            return ret;

        if (!s->num_refs) { /* intra */

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

                ff_spatial_idwt_slice2(&d, y+16); /* decode */

                s->diracdsp.put_signed_rect_clamped(frame + y*p->stride, p->stride,

                                                    p->idwt_buf + y*p->idwt_stride, p->idwt_stride, p->width, 16);

            }

        } else { /* inter */

            int rowheight = p->ybsep*p->stride;

            select_dsp_funcs(s, p->width, p->height, p->xblen, p->yblen);

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

                interpolate_refplane(s, s->ref_pics[i], comp, p->width, p->height);

            memset(s->mctmp, 0, 4*p->yoffset*p->stride);

            dsty = -p->yoffset;

            for (y = 0; y < s->blheight; y++) {

                int h     = 0,

                    start = FFMAX(dsty, 0);

                uint16_t *mctmp    = s->mctmp + y*rowheight;

                DiracBlock *blocks = s->blmotion + y*s->blwidth;

                init_obmc_weights(s, p, y);

                if (y == s->blheight-1 || start+p->ybsep > p->height)

                    h = p->height - start;

                else

                    h = p->ybsep - (start - dsty);

                if (h < 0)

                    break;

                memset(mctmp+2*p->yoffset*p->stride, 0, 2*rowheight);

                mc_row(s, blocks, mctmp, comp, dsty);

                mctmp += (start - dsty)*p->stride + p->xoffset;

                ff_spatial_idwt_slice2(&d, start + h); /* decode */

                s->diracdsp.add_rect_clamped(frame + start*p->stride, mctmp, p->stride,

                                             p->idwt_buf + start*p->idwt_stride, p->idwt_stride, p->width, h);

                dsty += p->ybsep;

            }

        }

    }

    return 0;

}


static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)

{

    MOVContext* mov = (MOVContext *) s->priv_data;

    MOVStreamContext* sc;

    int32_t i, a, b, m;

    int64_t start_time;

    int32_t seek_sample, sample;

    int32_t duration;

    int32_t count;

    int32_t chunk;

    int32_t left_in_chunk;

    int64_t chunk_file_offset;

    int64_t sample_file_offset;

    int32_t first_chunk_sample;

    int32_t sample_to_chunk_idx;

    int sample_to_time_index;

    long sample_to_time_sample = 0;

    uint64_t sample_to_time_time = 0;

    int mov_idx;

    // Find the corresponding mov stream

    for (mov_idx = 0; mov_idx < mov->total_streams; mov_idx++)

        if (mov->streams[mov_idx]->ffindex == stream_index)

            break;

    if (mov_idx == mov->total_streams) {

        av_log(s, AV_LOG_ERROR, "mov: requested stream was not found in mov streams (idx=%i)\n", stream_index);

        return -1;

    }

    sc = mov->streams[mov_idx];

    sample_time *= s->streams[stream_index]->time_base.num;

    // Step 1. Find the edit that contains the requested time (elst)

    if (sc->edit_count && 0) {

        // FIXME should handle edit list

        av_log(s, AV_LOG_ERROR, "mov: does not handle seeking in files that contain edit list (c:%d)\n", sc->edit_count);

        return -1;

    }

    // Step 2. Find the corresponding sample using the Time-to-sample atom (stts) */

    dprintf("Searching for time %li in stream #%i (time_scale=%i)\n", (long)sample_time, mov_idx, sc->time_scale);

    start_time = 0; // FIXME use elst atom

    sample = 1; // sample are 0 based in table

    for (i = 0; i < sc->stts_count; i++) {

        count = sc->stts_data[i].count;

        duration = sc->stts_data[i].duration;

        if ((start_time + count*duration) > sample_time) {

            sample_to_time_time = start_time;

            sample_to_time_index = i;

            sample_to_time_sample = sample;

            sample += (sample_time - start_time) / duration;

            break;

        }

        sample += count;

        start_time += count * duration;

    }

    sample_to_time_time = start_time;

    sample_to_time_index = i;

    /* NOTE: despite what qt doc say, the dt value (Display Time in qt vocabulary) computed with the stts atom

       is a decoding time stamp (dts) not a presentation time stamp. And as usual dts != pts for stream with b frames */

    dprintf("Found time %li at sample #%u\n", (long)sample_time, sample);

    if (sample > sc->sample_count) {

        av_log(s, AV_LOG_ERROR, "mov: sample pos is too high, unable to seek (req. sample=%i, sample count=%ld)\n", sample, sc->sample_count);

        return -1;

    }

    // Step 3. Find the prior sync. sample using the Sync sample atom (stss)

    if (sc->keyframes) {

        a = 0;

        b = sc->keyframe_count - 1;

        while (a < b) {

            m = (a + b + 1) >> 1;

            if (sc->keyframes[m] > sample) {

                b = m - 1;

            } else {

                a = m;

            }

        }

        // for low latency prob: always use the previous keyframe, just uncomment the next line

        // if (a) a--;

        seek_sample = sc->keyframes[a];

    }

    else

        seek_sample = sample; // else all samples are key frames

    dprintf("Found nearest keyframe at sample #%i \n", seek_sample);

    // Step 4. Find the chunk of the sample using the Sample-to-chunk-atom (stsc)

    for (first_chunk_sample = 1, i = 0; i < (sc->sample_to_chunk_sz - 1); i++) {

        b = (sc->sample_to_chunk[i + 1].first - sc->sample_to_chunk[i].first) * sc->sample_to_chunk[i].count;

        if (seek_sample >= first_chunk_sample && seek_sample < (first_chunk_sample + b))

            break;

        first_chunk_sample += b;

    }

    chunk = sc->sample_to_chunk[i].first + (seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count;

    left_in_chunk = sc->sample_to_chunk[i].count - (seek_sample - first_chunk_sample) % sc->sample_to_chunk[i].count;

    first_chunk_sample += ((seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count) * sc->sample_to_chunk[i].count;

    sample_to_chunk_idx = i;

    dprintf("Sample was found in chunk #%i at sample offset %i (idx %i)\n", chunk, seek_sample - first_chunk_sample, sample_to_chunk_idx);

    // Step 5. Find the offset of the chunk using the chunk offset atom

    if (!sc->chunk_offsets) {

        av_log(s, AV_LOG_ERROR, "mov: no chunk offset atom, unable to seek\n");

        return -1;

    }

    if (chunk > sc->chunk_count) {

        av_log(s, AV_LOG_ERROR, "mov: chunk offset atom too short, unable to seek (req. chunk=%i, chunk count=%li)\n", chunk, sc->chunk_count);

        return -1;

    }

    chunk_file_offset = sc->chunk_offsets[chunk - 1];

    dprintf("Chunk file offset is #%"PRIu64"\n", chunk_file_offset);

    // Step 6. Find the byte offset within the chunk using the sample size atom

    sample_file_offset = chunk_file_offset;

    if (sc->sample_size)

        sample_file_offset += (seek_sample - first_chunk_sample) * sc->sample_size;

    else {

        for (i = 0; i < (seek_sample - first_chunk_sample); i++) {

        sample_file_offset += sc->sample_sizes[first_chunk_sample + i - 1];

        }

    }

    dprintf("Sample file offset is #%"PRIu64"\n", sample_file_offset);

    // Step 6. Update the parser

    mov->partial = sc;

    mov->next_chunk_offset = sample_file_offset;

    // Update current stream state

    sc->current_sample = seek_sample - 1;  // zero based

    sc->left_in_chunk = left_in_chunk;

    sc->next_chunk = chunk; // +1 -1 (zero based)

    sc->sample_to_chunk_index = sample_to_chunk_idx;

    // Update other streams

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

        MOVStreamContext *msc;

        if (i == mov_idx) continue;

        // Find the nearest 'next' chunk

        msc = mov->streams[i];

        a = 0;

        b = msc->chunk_count - 1;

        while (a < b) {

            m = (a + b + 1) >> 1;

            if (msc->chunk_offsets[m] > chunk_file_offset) {

                b = m - 1;

            } else {

                a = m;

            }

        }

        msc->next_chunk = a;

        if (msc->chunk_offsets[a] < chunk_file_offset && a < (msc->chunk_count-1))

            msc->next_chunk ++;

        dprintf("Nearest next chunk for stream #%i is #%li @%"PRId64"\n", i, msc->next_chunk+1, msc->chunk_offsets[msc->next_chunk]);

        // Compute sample count and index in the sample_to_chunk table (what a pity)

        msc->sample_to_chunk_index = 0;

        msc->current_sample = 0;

        for(;  msc->sample_to_chunk_index < (msc->sample_to_chunk_sz - 1)

            && msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first <= (1 + msc->next_chunk); msc->sample_to_chunk_index++) {

            msc->current_sample += (msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first - msc->sample_to_chunk[msc->sample_to_chunk_index].first) \

            * msc->sample_to_chunk[msc->sample_to_chunk_index].count;

        }

        msc->current_sample += (msc->next_chunk - (msc->sample_to_chunk[msc->sample_to_chunk_index].first - 1)) * sc->sample_to_chunk[msc->sample_to_chunk_index].count;

        msc->left_in_chunk = msc->sample_to_chunk[msc->sample_to_chunk_index].count - 1;

        // Find corresponding position in stts (used later to compute dts)

        sample = 0;

        start_time = 0;

        for (msc->sample_to_time_index = 0; msc->sample_to_time_index < msc->stts_count; msc->sample_to_time_index++) {

            count = msc->stts_data[msc->sample_to_time_index].count;

            duration = msc->stts_data[msc->sample_to_time_index].duration;

            if ((sample + count - 1) > msc->current_sample) {

                msc->sample_to_time_time = start_time;

                msc->sample_to_time_sample = sample;

                break;

            }

            sample += count;

            start_time += count * duration;

        }

        sample = 0;

        for (msc->sample_to_ctime_index = 0; msc->sample_to_ctime_index < msc->ctts_count; msc->sample_to_ctime_index++) {

            count = msc->ctts_data[msc->sample_to_ctime_index].count;

            duration = msc->ctts_data[msc->sample_to_ctime_index].duration;

            if ((sample + count - 1) > msc->current_sample) {

                msc->sample_to_ctime_sample = sample;

                break;

            }

            sample += count;

        }

        dprintf("Next Sample for stream #%i is #%li @%li\n", i, msc->current_sample + 1, msc->sample_to_chunk_index + 1);

    }

    return 0;

}


static always_inline int dv_rl2vlc_size(int run, int l)

{

    int level = (l ^ (l >> 8)) - (l >> 8);

    int size;

    if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {

	size = dv_vlc_map[run][level].size;

    }

    else {

	size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16;

	if (run) {

	    size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;

	}

    }

    return size;

}


static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic,

                                const uint8_t *src, int src_size)

{

    GetByteContext gb;

    GetBitContext  gb2;

    int nslices, slice, slice_height;

    uint32_t off, slice_size;

    uint8_t *Y, *U, *V;

    int ret;

    bytestream2_init(&gb, src, src_size);

    nslices = bytestream2_get_le16(&gb);

    off = FFALIGN(nslices * 4 + 2, 16);

    if (src_size < off) {

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

        return AVERROR_INVALIDDATA;

    }

    if (!nslices || avctx->height % nslices) {

        avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,

                              avctx->width, avctx->height);

        return AVERROR_PATCHWELCOME;

    }

    slice_height = avctx->height / nslices;

    avctx->pix_fmt = AV_PIX_FMT_YUV444P;

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

        return ret;

    Y = pic->data[0];

    U = pic->data[1];

    V = pic->data[2];

    for (slice = 0; slice < nslices; slice++) {

        slice_size = bytestream2_get_le32(&gb);

        ret = check_slice_size(avctx, src, src_size, slice_size, off);

        if (ret < 0)

            return ret;

        init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);

        dx2_decode_slice_444(&gb2, avctx->width, slice_height, Y, U, V,

                             pic->linesize[0], pic->linesize[1],

                             pic->linesize[2]);

        Y += pic->linesize[0] * slice_height;

        U += pic->linesize[1] * slice_height;

        V += pic->linesize[2] * slice_height;

        off += slice_size;

    }

    return 0;

}


int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,

                          const AVFrame *frame, int *got_packet)

{

    NVENCSTATUS nv_status;

    CUresult cu_res;

    CUcontext dummy;

    NvencSurface *tmpoutsurf, *inSurf;

    int res;

    NvencContext *ctx = avctx->priv_data;

    NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;

    NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;

    NV_ENC_PIC_PARAMS pic_params = { 0 };

    pic_params.version = NV_ENC_PIC_PARAMS_VER;

    if (frame) {

        inSurf = get_free_frame(ctx);

        if (!inSurf) {

            av_log(avctx, AV_LOG_ERROR, "No free surfaces\n");

            return AVERROR_BUG;

        }

        cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context);

        if (cu_res != CUDA_SUCCESS) {

            av_log(avctx, AV_LOG_ERROR, "cuCtxPushCurrent failed\n");

            return AVERROR_EXTERNAL;

        }

        res = nvenc_upload_frame(avctx, frame, inSurf);

        cu_res = dl_fn->cuda_dl->cuCtxPopCurrent(&dummy);

        if (cu_res != CUDA_SUCCESS) {

            av_log(avctx, AV_LOG_ERROR, "cuCtxPopCurrent failed\n");

            return AVERROR_EXTERNAL;

        }

        if (res) {

            inSurf->lockCount = 0;

            return res;

        }

        pic_params.inputBuffer = inSurf->input_surface;

        pic_params.bufferFmt = inSurf->format;

        pic_params.inputWidth = avctx->width;

        pic_params.inputHeight = avctx->height;

        pic_params.inputPitch = inSurf->pitch;

        pic_params.outputBitstream = inSurf->output_surface;

        if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {

            if (frame->top_field_first)

                pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM;

            else

                pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP;

        } else {

            pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;

        }

        if (ctx->forced_idr >= 0 && frame->pict_type == AV_PICTURE_TYPE_I) {

            pic_params.encodePicFlags =

                ctx->forced_idr ? NV_ENC_PIC_FLAG_FORCEIDR : NV_ENC_PIC_FLAG_FORCEINTRA;

        } else {

            pic_params.encodePicFlags = 0;

        }

        pic_params.inputTimeStamp = frame->pts;

        nvenc_codec_specific_pic_params(avctx, &pic_params);

    } else {

        pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;

    }

    cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context);

    if (cu_res != CUDA_SUCCESS) {

        av_log(avctx, AV_LOG_ERROR, "cuCtxPushCurrent failed\n");

        return AVERROR_EXTERNAL;

    }

    nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);

    cu_res = dl_fn->cuda_dl->cuCtxPopCurrent(&dummy);

    if (cu_res != CUDA_SUCCESS) {

        av_log(avctx, AV_LOG_ERROR, "cuCtxPopCurrent failed\n");

        return AVERROR_EXTERNAL;

    }

    if (nv_status != NV_ENC_SUCCESS &&

        nv_status != NV_ENC_ERR_NEED_MORE_INPUT)

        return nvenc_print_error(avctx, nv_status, "EncodePicture failed!");

    if (frame) {

        av_fifo_generic_write(ctx->output_surface_queue, &inSurf, sizeof(inSurf), NULL);

        timestamp_queue_enqueue(ctx->timestamp_list, frame->pts);

        if (ctx->initial_pts[0] == AV_NOPTS_VALUE)

            ctx->initial_pts[0] = frame->pts;

        else if (ctx->initial_pts[1] == AV_NOPTS_VALUE)

            ctx->initial_pts[1] = frame->pts;

    }

    /* all the pending buffers are now ready for output */

    if (nv_status == NV_ENC_SUCCESS) {

        while (av_fifo_size(ctx->output_surface_queue) > 0) {

            av_fifo_generic_read(ctx->output_surface_queue, &tmpoutsurf, sizeof(tmpoutsurf), NULL);

            av_fifo_generic_write(ctx->output_surface_ready_queue, &tmpoutsurf, sizeof(tmpoutsurf), NULL);

        }

    }

    if (output_ready(avctx, !frame)) {

        av_fifo_generic_read(ctx->output_surface_ready_queue, &tmpoutsurf, sizeof(tmpoutsurf), NULL);

        res = process_output_surface(avctx, pkt, tmpoutsurf);

        if (res)

            return res;

        av_assert0(tmpoutsurf->lockCount);

        tmpoutsurf->lockCount--;

        *got_packet = 1;

    } else {

        *got_packet = 0;

    }

    return 0;

}


static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c)

{

    uint8_t byte;

    if (s->buf_end - s->buf < 5)

        return AVERROR(EINVAL);

    c->nreslevels = bytestream_get_byte(&s->buf) + 1; // num of resolution levels - 1

    /* compute number of resolution levels to decode */

    if (c->nreslevels < s->reduction_factor)

        c->nreslevels2decode = 1;

    else

        c->nreslevels2decode = c->nreslevels - s->reduction_factor;

    c->log2_cblk_width  = bytestream_get_byte(&s->buf) + 2; // cblk width

    c->log2_cblk_height = bytestream_get_byte(&s->buf) + 2; // cblk height

    c->cblk_style = bytestream_get_byte(&s->buf);

    if (c->cblk_style != 0) { // cblk style

        av_log(s->avctx, AV_LOG_ERROR, "no extra cblk styles supported\n");

        return -1;

    }

    c->transform = bytestream_get_byte(&s->buf); // DWT transformation type

    /* set integer 9/7 DWT in case of BITEXACT flag */

    if ((s->avctx->flags & CODEC_FLAG_BITEXACT) && (c->transform == FF_DWT97))

        c->transform = FF_DWT97_INT;

    if (c->csty & JPEG2000_CSTY_PREC) {

        int i;

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

            byte = bytestream_get_byte(&s->buf);

            c->log2_prec_widths[i]  =  byte       & 0x0F;    // precinct PPx

            c->log2_prec_heights[i] = (byte >> 4) & 0x0F;    // precinct PPy

        }

    }

    return 0;

}


static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)

{

    AVFilterContext *ctx = inlink->dst;

    TInterlaceContext *tinterlace = ctx->priv;

    if (tinterlace->cur)

        avfilter_unref_buffer(tinterlace->cur);

    tinterlace->cur  = tinterlace->next;

    tinterlace->next = picref;

}