static void dv_decode_ac(DVVideoDecodeContext *s,

                         BlockInfo *mb, DCTELEM *block, int last_index)

{

    int last_re_index;

    int shift_offset = mb->shift_offset;

    const UINT8 *scan_table = mb->scan_table;

    const UINT8 *shift_table = mb->shift_table;

    int pos = mb->pos;

    int level, pos1, sign, run;

    int partial_bit_count;

    OPEN_READER(re, &s->gb);

#ifdef VLC_DEBUG

    printf("start\n");

#endif

    /* if we must parse a partial vlc, we do it here */

    partial_bit_count = mb->partial_bit_count;

    if (partial_bit_count > 0) {

        UINT8 buf[4];

        UINT32 v;

        int l, l1;

        GetBitContext gb1;

        /* build the dummy bit buffer */

        l = 16 - partial_bit_count;

        UPDATE_CACHE(re, &s->gb);

#ifdef VLC_DEBUG

        printf("show=%04x\n", SHOW_UBITS(re, &s->gb, 16));

#endif

        v = (mb->partial_bit_buffer << l) | SHOW_UBITS(re, &s->gb, l);

        buf[0] = v >> 8;

        buf[1] = v;

#ifdef VLC_DEBUG

        printf("v=%04x cnt=%d %04x\n",

               v, partial_bit_count, (mb->partial_bit_buffer << l));

#endif

        /* try to read the codeword */

        init_get_bits(&gb1, buf, 4);

        {

            OPEN_READER(re1, &gb1);

            UPDATE_CACHE(re1, &gb1);

            GET_RL_VLC(level, run, re1, &gb1, dv_rl_vlc[0],

                       TEX_VLC_BITS, 2);

            l = re1_index;

            CLOSE_READER(re1, &gb1);

        }

#ifdef VLC_DEBUG

        printf("****run=%d level=%d size=%d\n", run, level, l);

#endif

        /* compute codeword length */

        l1 = (level != 256 && level != 0);

        /* if too long, we cannot parse */

        l -= partial_bit_count;

        if ((re_index + l + l1) > last_index)

            return;

        /* skip read bits */

        last_re_index = 0; /* avoid warning */

        re_index += l;

        /* by definition, if we can read the vlc, all partial bits

           will be read (otherwise we could have read the vlc before) */

        mb->partial_bit_count = 0;

        UPDATE_CACHE(re, &s->gb);

        goto handle_vlc;

    }

    /* get the AC coefficients until last_index is reached */

    for(;;) {

        UPDATE_CACHE(re, &s->gb);

#ifdef VLC_DEBUG

        printf("%2d: bits=%04x index=%d\n",

               pos, SHOW_UBITS(re, &s->gb, 16), re_index);

#endif

        last_re_index = re_index;

        GET_RL_VLC(level, run, re, &s->gb, dv_rl_vlc[0],

                   TEX_VLC_BITS, 2);

    handle_vlc:

#ifdef VLC_DEBUG

        printf("run=%d level=%d\n", run, level);

#endif

        if (level == 256) {

            if (re_index > last_index) {

            cannot_read:

                /* put position before read code */

                re_index = last_re_index;

                mb->eob_reached = 0;

                break;

            }

            /* EOB */

            mb->eob_reached = 1;

            break;

        } else if (level != 0) {

            if ((re_index + 1) > last_index)

                goto cannot_read;

            sign = SHOW_SBITS(re, &s->gb, 1);

            level = (level ^ sign) - sign;

            LAST_SKIP_BITS(re, &s->gb, 1);

            pos += run;

            /* error */

            if (pos >= 64) {

                goto read_error;

            }

            pos1 = scan_table[pos];

            level = level << (shift_table[pos1] + shift_offset);

            block[pos1] = level;

            //            printf("run=%d level=%d shift=%d\n", run, level, shift_table[pos1]);

        } else {

            if (re_index > last_index)

                goto cannot_read;

            /* level is zero: means run without coding. No

               sign is coded */

            pos += run;

            /* error */

            if (pos >= 64) {

            read_error:

#if defined(VLC_DEBUG) || 1

                printf("error pos=%d\n", pos);

#endif

                /* for errors, we consider the eob is reached */

                mb->eob_reached = 1;

                break;

            }

        }

    }

    CLOSE_READER(re, &s->gb);

    mb->pos = pos;

}


static int expand_rle_row16(SgiState *s, uint16_t *out_buf,

                            int len, int pixelstride)

{

    unsigned short pixel;

    unsigned char count;

    unsigned short *orig = out_buf;

    uint16_t *out_end = out_buf + len;

    while (out_buf < out_end) {

        if (bytestream2_get_bytes_left(&s->g) < 2)

            return AVERROR_INVALIDDATA;

        pixel = bytestream2_get_be16u(&s->g);

        if (!(count = (pixel & 0x7f)))

            break;

        /* Check for buffer overflow. */

        if (pixelstride * (count - 1) >= len) {

            av_log(s->avctx, AV_LOG_ERROR, "Invalid pixel count.\n");

            return AVERROR_INVALIDDATA;

        }

        if (pixel & 0x80) {

            while (count--) {

                pixel = bytestream2_get_ne16(&s->g);

                AV_WN16A(out_buf, pixel);

                out_buf += pixelstride;

            }

        } else {

            pixel = bytestream2_get_ne16(&s->g);

            while (count--) {

                AV_WN16A(out_buf, pixel);

                out_buf += pixelstride;

            }

        }

    }

    return (out_buf - orig) / pixelstride;

}


void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx,

              void *retaddr)

{

    TranslationBlock *tb;

    CPUState *saved_env;

    unsigned long pc;

    int ret;

    saved_env = env;

    ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx);

    if (unlikely(ret)) {

        if (retaddr) {

            /* now we have a real cpu fault */

            pc = (unsigned long)retaddr;

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

            }

        }

        raise_exception(env->exception_index);

    }

    env = saved_env;

}


static int webvtt_read_header(AVFormatContext *s)

{

    WebVTTContext *webvtt = s->priv_data;

    AVBPrint header, cue;

    int res = 0;

    AVStream *st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    avpriv_set_pts_info(st, 64, 1, 1000);

    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;

    st->codec->codec_id   = AV_CODEC_ID_WEBVTT;

    st->disposition |= webvtt->kind;

    av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED);

    av_bprint_init(&cue,    0, AV_BPRINT_SIZE_UNLIMITED);

    for (;;) {

        int i;

        int64_t pos;

        AVPacket *sub;

        const char *p, *identifier, *settings;

        int identifier_len, settings_len;

        int64_t ts_start, ts_end;

        ff_subtitles_read_chunk(s->pb, &cue);

        if (!cue.len)

            break;

        p = identifier = cue.str;

        pos = avio_tell(s->pb);

        /* ignore header chunk */

        if (!strncmp(p, "\xEF\xBB\xBFWEBVTT", 9) ||

            !strncmp(p, "WEBVTT", 6))

            continue;

        /* optional cue identifier (can be a number like in SRT or some kind of

         * chaptering id) */

        for (i = 0; p[i] && p[i] != '\n' && p[i] != '\r'; i++) {

            if (!strncmp(p + i, "-->", 3)) {

                identifier = NULL;

                break;

            }

        }

        if (!identifier)

            identifier_len = 0;

        else {

            identifier_len = strcspn(p, "\r\n");

            p += identifier_len;

            if (*p == '\r')

                p++;

            if (*p == '\n')

                p++;

        }

        /* cue timestamps */

        if ((ts_start = read_ts(p)) == AV_NOPTS_VALUE)

            break;

        if (!(p = strstr(p, "-->")))

            break;

        p += 3;

        do p++; while (*p == ' ' || *p == '\t');

        if ((ts_end = read_ts(p)) == AV_NOPTS_VALUE)

            break;

        /* optional cue settings */

        p += strcspn(p, "\n\t ");

        while (*p == '\t' || *p == ' ')

            p++;

        settings = p;

        settings_len = strcspn(p, "\r\n");

        p += settings_len;

        if (*p == '\r')

            p++;

        if (*p == '\n')

            p++;

        /* create packet */

        sub = ff_subtitles_queue_insert(&webvtt->q, p, strlen(p), 0);

        if (!sub) {

            res = AVERROR(ENOMEM);

            goto end;

        }

        sub->pos = pos;

        sub->pts = ts_start;

        sub->duration = ts_end - ts_start;

#define SET_SIDE_DATA(name, type) do {                                  \

    if (name##_len) {                                                   \

        uint8_t *buf = av_packet_new_side_data(sub, type, name##_len);  \

        if (!buf) {                                                     \

            res = AVERROR(ENOMEM);                                      \

            goto end;                                                   \

        }                                                               \

        memcpy(buf, name, name##_len);                                  \

    }                                                                   \

} while (0)

        SET_SIDE_DATA(identifier, AV_PKT_DATA_WEBVTT_IDENTIFIER);

        SET_SIDE_DATA(settings,   AV_PKT_DATA_WEBVTT_SETTINGS);

    }

    ff_subtitles_queue_finalize(&webvtt->q);

end:

    av_bprint_finalize(&cue,    NULL);

    av_bprint_finalize(&header, NULL);

    return res;

}


int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){

    MpegEncContext * const s = &h->s;

    unsigned int pps_id= get_ue_golomb(&s->gb);

    PPS *pps;

    const int qp_bd_offset = 6*(h->sps.bit_depth_luma-8);

    int bits_left;

    if(pps_id >= MAX_PPS_COUNT) {

        av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id);

        return -1;

    }

    pps= av_mallocz(sizeof(PPS));

    if(pps == NULL)

        return -1;

    pps->sps_id= get_ue_golomb_31(&s->gb);

    if((unsigned)pps->sps_id>=MAX_SPS_COUNT || h->sps_buffers[pps->sps_id] == NULL){

        av_log(h->s.avctx, AV_LOG_ERROR, "sps_id out of range\n");

        goto fail;

    }

    pps->cabac= get_bits1(&s->gb);

    pps->pic_order_present= get_bits1(&s->gb);

    pps->slice_group_count= get_ue_golomb(&s->gb) + 1;

    if(pps->slice_group_count > 1 ){

        pps->mb_slice_group_map_type= get_ue_golomb(&s->gb);

        av_log(h->s.avctx, AV_LOG_ERROR, "FMO not supported\n");

        switch(pps->mb_slice_group_map_type){

        case 0:

#if 0

|   for( i = 0; i <= num_slice_groups_minus1; i++ ) |   |        |

|    run_length[ i ]                                |1  |ue(v)   |

#endif

            break;

        case 2:

#if 0

|   for( i = 0; i < num_slice_groups_minus1; i++ )  |   |        |

|{                                                  |   |        |

|    top_left_mb[ i ]                               |1  |ue(v)   |

|    bottom_right_mb[ i ]                           |1  |ue(v)   |

|   }                                               |   |        |

#endif

            break;

        case 3:

        case 4:

        case 5:

#if 0

|   slice_group_change_direction_flag               |1  |u(1)    |

|   slice_group_change_rate_minus1                  |1  |ue(v)   |

#endif

            break;

        case 6:

#if 0

|   slice_group_id_cnt_minus1                       |1  |ue(v)   |

|   for( i = 0; i <= slice_group_id_cnt_minus1; i++ |   |        |

|)                                                  |   |        |

|    slice_group_id[ i ]                            |1  |u(v)    |

#endif

            break;

        }

    }

    pps->ref_count[0]= get_ue_golomb(&s->gb) + 1;

    pps->ref_count[1]= get_ue_golomb(&s->gb) + 1;

    if(pps->ref_count[0]-1 > 32-1 || pps->ref_count[1]-1 > 32-1){

        av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow (pps)\n");

        goto fail;

    }

    pps->weighted_pred= get_bits1(&s->gb);

    pps->weighted_bipred_idc= get_bits(&s->gb, 2);

    pps->init_qp= get_se_golomb(&s->gb) + 26 + qp_bd_offset;

    pps->init_qs= get_se_golomb(&s->gb) + 26 + qp_bd_offset;

    pps->chroma_qp_index_offset[0]= get_se_golomb(&s->gb);

    pps->deblocking_filter_parameters_present= get_bits1(&s->gb);

    pps->constrained_intra_pred= get_bits1(&s->gb);

    pps->redundant_pic_cnt_present = get_bits1(&s->gb);

    pps->transform_8x8_mode= 0;

    h->dequant_coeff_pps= -1; //contents of sps/pps can change even if id doesn't, so reinit

    memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4, sizeof(pps->scaling_matrix4));

    memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8, sizeof(pps->scaling_matrix8));

    bits_left = bit_length - get_bits_count(&s->gb);

    if(bits_left > 0){

        pps->transform_8x8_mode= get_bits1(&s->gb);

        decode_scaling_matrices(h, h->sps_buffers[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8);

        pps->chroma_qp_index_offset[1]= get_se_golomb(&s->gb); //second_chroma_qp_index_offset

    } else {

        pps->chroma_qp_index_offset[1]= pps->chroma_qp_index_offset[0];

    }

    build_qp_table(pps, 0, pps->chroma_qp_index_offset[0], h->sps.bit_depth_luma);

    build_qp_table(pps, 1, pps->chroma_qp_index_offset[1], h->sps.bit_depth_luma);

    if(pps->chroma_qp_index_offset[0] != pps->chroma_qp_index_offset[1])

        pps->chroma_qp_diff= 1;

    if(s->avctx->debug&FF_DEBUG_PICT_INFO){

        av_log(h->s.avctx, AV_LOG_DEBUG, "pps:%u sps:%u %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d/%d %s %s %s %s\n",

               pps_id, pps->sps_id,

               pps->cabac ? "CABAC" : "CAVLC",

               pps->slice_group_count,

               pps->ref_count[0], pps->ref_count[1],

               pps->weighted_pred ? "weighted" : "",

               pps->init_qp, pps->init_qs, pps->chroma_qp_index_offset[0], pps->chroma_qp_index_offset[1],

               pps->deblocking_filter_parameters_present ? "LPAR" : "",

               pps->constrained_intra_pred ? "CONSTR" : "",

               pps->redundant_pic_cnt_present ? "REDU" : "",

               pps->transform_8x8_mode ? "8x8DCT" : ""

               );

    }

    av_free(h->pps_buffers[pps_id]);

    h->pps_buffers[pps_id]= pps;

    return 0;

fail:

    av_free(pps);

    return -1;

}


static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){

    AVFrame *pic=NULL;

    int i;

    const int encoding_delay= s->max_b_frames;

    int direct=1;

  if(pic_arg){

    if(encoding_delay && !(s->flags&CODEC_FLAG_INPUT_PRESERVED)) direct=0;

    if(pic_arg->linesize[0] != s->linesize) direct=0;

    if(pic_arg->linesize[1] != s->uvlinesize) direct=0;

    if(pic_arg->linesize[2] != s->uvlinesize) direct=0;

//    printf("%d %d %d %d\n",pic_arg->linesize[0], pic_arg->linesize[1], s->linesize, s->uvlinesize);

    if(direct){

        i= find_unused_picture(s, 1);

        pic= (AVFrame*)&s->picture[i];

        pic->reference= 3;

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

            pic->data[i]= pic_arg->data[i];

            pic->linesize[i]= pic_arg->linesize[i];

        }

        alloc_picture(s, (Picture*)pic, 1);

    }else{

        i= find_unused_picture(s, 0);

        pic= (AVFrame*)&s->picture[i];

        pic->reference= 3;

        alloc_picture(s, (Picture*)pic, 0);

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

            /* the input will be 16 pixels to the right relative to the actual buffer start

             * and the current_pic, so the buffer can be reused, yes its not beatifull

             */

            pic->data[i]+= 16;

        }

        if(   pic->data[0] == pic_arg->data[0]

           && pic->data[1] == pic_arg->data[1]

           && pic->data[2] == pic_arg->data[2]){

       // empty

        }else{

            int h_chroma_shift, v_chroma_shift;

            avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift);

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

                int src_stride= pic_arg->linesize[i];

                int dst_stride= i ? s->uvlinesize : s->linesize;

                int h_shift= i ? h_chroma_shift : 0;

                int v_shift= i ? v_chroma_shift : 0;

                int w= s->width >>h_shift;

                int h= s->height>>v_shift;

                uint8_t *src= pic_arg->data[i];

                uint8_t *dst= pic->data[i];

                if(src_stride==dst_stride)

                    memcpy(dst, src, src_stride*h);

                else{

                    while(h--){

                        memcpy(dst, src, w);

                        dst += dst_stride;

                        src += src_stride;

                    }

                }

            }

        }

    }

    pic->quality= pic_arg->quality;

    pic->pict_type= pic_arg->pict_type;

    pic->pts = pic_arg->pts;

    if(s->input_picture[encoding_delay])

        pic->display_picture_number= s->input_picture[encoding_delay]->display_picture_number + 1;

  }

    /* shift buffer entries */

    for(i=1; i<MAX_PICTURE_COUNT /*s->encoding_delay+1*/; i++)

        s->input_picture[i-1]= s->input_picture[i];

    s->input_picture[encoding_delay]= (Picture*)pic;

    return 0;

}


int av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame)

{

    BufferSinkContext *s    = ctx->priv;

    AVFilterLink      *link = ctx->inputs[0];

    int ret;

    if ((ret = ff_request_frame(link)) < 0)

        return ret;

    if (!s->cur_frame)

        return AVERROR(EINVAL);

    av_frame_move_ref(frame, s->cur_frame);

    av_frame_free(&s->cur_frame);

    return 0;

}


static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,

                        MemTxAttrs attrs)

{

    ARMCPU *cpu = s->cpu;

    switch (offset) {

    case 0x380 ... 0x3bf: /* NVIC_ITNS<n> */

    {

        int startvec = 32 * (offset - 0x380) + NVIC_FIRST_IRQ;

        int i;

        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            goto bad_offset;

        }

        if (!attrs.secure) {

            break;

        }

        for (i = 0; i < 32 && startvec + i < s->num_irq; i++) {

            s->itns[startvec + i] = (value >> i) & 1;

        }

        nvic_irq_update(s);

        break;

    }

    case 0xd04: /* Interrupt Control State (ICSR) */

        if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {

            if (value & (1 << 31)) {

                armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);

            } else if (value & (1 << 30) &&

                       arm_feature(&cpu->env, ARM_FEATURE_V8)) {

                /* PENDNMICLR didn't exist in v7M */

                armv7m_nvic_clear_pending(s, ARMV7M_EXCP_NMI, false);

            }

        }

        if (value & (1 << 28)) {

            armv7m_nvic_set_pending(s, ARMV7M_EXCP_PENDSV, attrs.secure);

        } else if (value & (1 << 27)) {

            armv7m_nvic_clear_pending(s, ARMV7M_EXCP_PENDSV, attrs.secure);

        }

        if (value & (1 << 26)) {

            armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, attrs.secure);

        } else if (value & (1 << 25)) {

            armv7m_nvic_clear_pending(s, ARMV7M_EXCP_SYSTICK, attrs.secure);

        }

        break;

    case 0xd08: /* Vector Table Offset.  */

        cpu->env.v7m.vecbase[attrs.secure] = value & 0xffffff80;

        break;

    case 0xd0c: /* Application Interrupt/Reset Control (AIRCR) */

        if ((value >> R_V7M_AIRCR_VECTKEY_SHIFT) == 0x05fa) {

            if (value & R_V7M_AIRCR_SYSRESETREQ_MASK) {

                if (attrs.secure ||

                    !(cpu->env.v7m.aircr & R_V7M_AIRCR_SYSRESETREQS_MASK)) {

                    qemu_irq_pulse(s->sysresetreq);

                }

            }

            if (value & R_V7M_AIRCR_VECTCLRACTIVE_MASK) {

                qemu_log_mask(LOG_GUEST_ERROR,

                              "Setting VECTCLRACTIVE when not in DEBUG mode "

                              "is UNPREDICTABLE\n");

            }

            if (value & R_V7M_AIRCR_VECTRESET_MASK) {

                /* NB: this bit is RES0 in v8M */

                qemu_log_mask(LOG_GUEST_ERROR,

                              "Setting VECTRESET when not in DEBUG mode "

                              "is UNPREDICTABLE\n");

            }

            s->prigroup[attrs.secure] = extract32(value,

                                                  R_V7M_AIRCR_PRIGROUP_SHIFT,

                                                  R_V7M_AIRCR_PRIGROUP_LENGTH);

            if (attrs.secure) {

                /* These bits are only writable by secure */

                cpu->env.v7m.aircr = value &

                    (R_V7M_AIRCR_SYSRESETREQS_MASK |

                     R_V7M_AIRCR_BFHFNMINS_MASK |

                     R_V7M_AIRCR_PRIS_MASK);

                /* BFHFNMINS changes the priority of Secure HardFault, and

                 * allows a pending Non-secure HardFault to preempt (which

                 * we implement by marking it enabled).

                 */

                if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {

                    s->sec_vectors[ARMV7M_EXCP_HARD].prio = -3;

                    s->vectors[ARMV7M_EXCP_HARD].enabled = 1;

                } else {

                    s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1;

                    s->vectors[ARMV7M_EXCP_HARD].enabled = 0;

                }

            }

            nvic_irq_update(s);

        }

        break;

    case 0xd10: /* System Control.  */

        /* TODO: Implement control registers.  */

        qemu_log_mask(LOG_UNIMP, "NVIC: SCR unimplemented\n");

        break;

    case 0xd14: /* Configuration Control.  */

        /* Enforce RAZ/WI on reserved and must-RAZ/WI bits */

        value &= (R_V7M_CCR_STKALIGN_MASK |

                  R_V7M_CCR_BFHFNMIGN_MASK |

                  R_V7M_CCR_DIV_0_TRP_MASK |

                  R_V7M_CCR_UNALIGN_TRP_MASK |

                  R_V7M_CCR_USERSETMPEND_MASK |

                  R_V7M_CCR_NONBASETHRDENA_MASK);

        if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            /* v8M makes NONBASETHRDENA and STKALIGN be RES1 */

            value |= R_V7M_CCR_NONBASETHRDENA_MASK

                | R_V7M_CCR_STKALIGN_MASK;

        }

        if (attrs.secure) {

            /* the BFHFNMIGN bit is not banked; keep that in the NS copy */

            cpu->env.v7m.ccr[M_REG_NS] =

                (cpu->env.v7m.ccr[M_REG_NS] & ~R_V7M_CCR_BFHFNMIGN_MASK)

                | (value & R_V7M_CCR_BFHFNMIGN_MASK);

            value &= ~R_V7M_CCR_BFHFNMIGN_MASK;

        }

        cpu->env.v7m.ccr[attrs.secure] = value;

        break;

    case 0xd24: /* System Handler Control and State (SHCSR) */

        if (attrs.secure) {

            s->sec_vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0;

            /* Secure HardFault active bit cannot be written */

            s->sec_vectors[ARMV7M_EXCP_USAGE].active = (value & (1 << 3)) != 0;

            s->sec_vectors[ARMV7M_EXCP_SVC].active = (value & (1 << 7)) != 0;

            s->sec_vectors[ARMV7M_EXCP_PENDSV].active =

                (value & (1 << 10)) != 0;

            s->sec_vectors[ARMV7M_EXCP_SYSTICK].active =

                (value & (1 << 11)) != 0;

            s->sec_vectors[ARMV7M_EXCP_USAGE].pending =

                (value & (1 << 12)) != 0;

            s->sec_vectors[ARMV7M_EXCP_MEM].pending = (value & (1 << 13)) != 0;

            s->sec_vectors[ARMV7M_EXCP_SVC].pending = (value & (1 << 15)) != 0;

            s->sec_vectors[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;

            s->sec_vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;

            s->sec_vectors[ARMV7M_EXCP_USAGE].enabled =

                (value & (1 << 18)) != 0;

            s->sec_vectors[ARMV7M_EXCP_HARD].pending = (value & (1 << 21)) != 0;

            /* SecureFault not banked, but RAZ/WI to NS */

            s->vectors[ARMV7M_EXCP_SECURE].active = (value & (1 << 4)) != 0;

            s->vectors[ARMV7M_EXCP_SECURE].enabled = (value & (1 << 19)) != 0;

            s->vectors[ARMV7M_EXCP_SECURE].pending = (value & (1 << 20)) != 0;

        } else {

            s->vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0;

            if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {

                /* HARDFAULTPENDED is not present in v7M */

                s->vectors[ARMV7M_EXCP_HARD].pending = (value & (1 << 21)) != 0;

            }

            s->vectors[ARMV7M_EXCP_USAGE].active = (value & (1 << 3)) != 0;

            s->vectors[ARMV7M_EXCP_SVC].active = (value & (1 << 7)) != 0;

            s->vectors[ARMV7M_EXCP_PENDSV].active = (value & (1 << 10)) != 0;

            s->vectors[ARMV7M_EXCP_SYSTICK].active = (value & (1 << 11)) != 0;

            s->vectors[ARMV7M_EXCP_USAGE].pending = (value & (1 << 12)) != 0;

            s->vectors[ARMV7M_EXCP_MEM].pending = (value & (1 << 13)) != 0;

            s->vectors[ARMV7M_EXCP_SVC].pending = (value & (1 << 15)) != 0;

            s->vectors[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;

            s->vectors[ARMV7M_EXCP_USAGE].enabled = (value & (1 << 18)) != 0;

        }

        if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {

            s->vectors[ARMV7M_EXCP_BUS].active = (value & (1 << 1)) != 0;

            s->vectors[ARMV7M_EXCP_BUS].pending = (value & (1 << 14)) != 0;

            s->vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;

        }

        /* NMIACT can only be written if the write is of a zero, with

         * BFHFNMINS 1, and by the CPU in secure state via the NS alias.

         */

        if (!attrs.secure && cpu->env.v7m.secure &&

            (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) &&

            (value & (1 << 5)) == 0) {

            s->vectors[ARMV7M_EXCP_NMI].active = 0;

        }

        /* HARDFAULTACT can only be written if the write is of a zero

         * to the non-secure HardFault state by the CPU in secure state.

         * The only case where we can be targeting the non-secure HF state

         * when in secure state is if this is a write via the NS alias

         * and BFHFNMINS is 1.

         */

        if (!attrs.secure && cpu->env.v7m.secure &&

            (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) &&

            (value & (1 << 2)) == 0) {

            s->vectors[ARMV7M_EXCP_HARD].active = 0;

        }

        /* TODO: this is RAZ/WI from NS if DEMCR.SDME is set */

        s->vectors[ARMV7M_EXCP_DEBUG].active = (value & (1 << 8)) != 0;

        nvic_irq_update(s);

        break;

    case 0xd28: /* Configurable Fault Status.  */

        cpu->env.v7m.cfsr[attrs.secure] &= ~value; /* W1C */

        if (attrs.secure) {

            /* The BFSR bits [15:8] are shared between security states

             * and we store them in the NS copy.

             */

            cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK);

        }

        break;

    case 0xd2c: /* Hard Fault Status.  */

        cpu->env.v7m.hfsr &= ~value; /* W1C */

        break;

    case 0xd30: /* Debug Fault Status.  */

        cpu->env.v7m.dfsr &= ~value; /* W1C */

        break;

    case 0xd34: /* Mem Manage Address.  */

        cpu->env.v7m.mmfar[attrs.secure] = value;

        return;

    case 0xd38: /* Bus Fault Address.  */

        cpu->env.v7m.bfar = value;

        return;

    case 0xd3c: /* Aux Fault Status.  */

        qemu_log_mask(LOG_UNIMP,

                      "NVIC: Aux fault status registers unimplemented\n");

        break;

    case 0xd90: /* MPU_TYPE */

        return; /* RO */

    case 0xd94: /* MPU_CTRL */

        if ((value &

             (R_V7M_MPU_CTRL_HFNMIENA_MASK | R_V7M_MPU_CTRL_ENABLE_MASK))

            == R_V7M_MPU_CTRL_HFNMIENA_MASK) {

            qemu_log_mask(LOG_GUEST_ERROR, "MPU_CTRL: HFNMIENA and !ENABLE is "

                          "UNPREDICTABLE\n");

        }

        cpu->env.v7m.mpu_ctrl[attrs.secure]

            = value & (R_V7M_MPU_CTRL_ENABLE_MASK |

                       R_V7M_MPU_CTRL_HFNMIENA_MASK |

                       R_V7M_MPU_CTRL_PRIVDEFENA_MASK);

        tlb_flush(CPU(cpu));

        break;

    case 0xd98: /* MPU_RNR */

        if (value >= cpu->pmsav7_dregion) {

            qemu_log_mask(LOG_GUEST_ERROR, "MPU region out of range %"

                          PRIu32 "/%" PRIu32 "\n",

                          value, cpu->pmsav7_dregion);

        } else {

            cpu->env.pmsav7.rnr[attrs.secure] = value;

        }

        break;

    case 0xd9c: /* MPU_RBAR */

    case 0xda4: /* MPU_RBAR_A1 */

    case 0xdac: /* MPU_RBAR_A2 */

    case 0xdb4: /* MPU_RBAR_A3 */

    {

        int region;

        if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            /* PMSAv8M handling of the aliases is different from v7M:

             * aliases A1, A2, A3 override the low two bits of the region

             * number in MPU_RNR, and there is no 'region' field in the

             * RBAR register.

             */

            int aliasno = (offset - 0xd9c) / 8; /* 0..3 */

            region = cpu->env.pmsav7.rnr[attrs.secure];

            if (aliasno) {

                region = deposit32(region, 0, 2, aliasno);

            }

            if (region >= cpu->pmsav7_dregion) {

                return;

            }

            cpu->env.pmsav8.rbar[attrs.secure][region] = value;

            tlb_flush(CPU(cpu));

            return;

        }

        if (value & (1 << 4)) {

            /* VALID bit means use the region number specified in this

             * value and also update MPU_RNR.REGION with that value.

             */

            region = extract32(value, 0, 4);

            if (region >= cpu->pmsav7_dregion) {

                qemu_log_mask(LOG_GUEST_ERROR,

                              "MPU region out of range %u/%" PRIu32 "\n",

                              region, cpu->pmsav7_dregion);

                return;

            }

            cpu->env.pmsav7.rnr[attrs.secure] = region;

        } else {

            region = cpu->env.pmsav7.rnr[attrs.secure];

        }

        if (region >= cpu->pmsav7_dregion) {

            return;

        }

        cpu->env.pmsav7.drbar[region] = value & ~0x1f;

        tlb_flush(CPU(cpu));

        break;

    }

    case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */

    case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */

    case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */

    case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */

    {

        int region = cpu->env.pmsav7.rnr[attrs.secure];

        if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            /* PMSAv8M handling of the aliases is different from v7M:

             * aliases A1, A2, A3 override the low two bits of the region

             * number in MPU_RNR.

             */

            int aliasno = (offset - 0xd9c) / 8; /* 0..3 */

            region = cpu->env.pmsav7.rnr[attrs.secure];

            if (aliasno) {

                region = deposit32(region, 0, 2, aliasno);

            }

            if (region >= cpu->pmsav7_dregion) {

                return;

            }

            cpu->env.pmsav8.rlar[attrs.secure][region] = value;

            tlb_flush(CPU(cpu));

            return;

        }

        if (region >= cpu->pmsav7_dregion) {

            return;

        }

        cpu->env.pmsav7.drsr[region] = value & 0xff3f;

        cpu->env.pmsav7.dracr[region] = (value >> 16) & 0x173f;

        tlb_flush(CPU(cpu));

        break;

    }

    case 0xdc0: /* MPU_MAIR0 */

        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            goto bad_offset;

        }

        if (cpu->pmsav7_dregion) {

            /* Register is RES0 if no MPU regions are implemented */

            cpu->env.pmsav8.mair0[attrs.secure] = value;

        }

        /* We don't need to do anything else because memory attributes

         * only affect cacheability, and we don't implement caching.

         */

        break;

    case 0xdc4: /* MPU_MAIR1 */

        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            goto bad_offset;

        }

        if (cpu->pmsav7_dregion) {

            /* Register is RES0 if no MPU regions are implemented */

            cpu->env.pmsav8.mair1[attrs.secure] = value;

        }

        /* We don't need to do anything else because memory attributes

         * only affect cacheability, and we don't implement caching.

         */

        break;

    case 0xdd0: /* SAU_CTRL */

        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            goto bad_offset;

        }

        if (!attrs.secure) {

            return;

        }

        cpu->env.sau.ctrl = value & 3;

        break;

    case 0xdd4: /* SAU_TYPE */

        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            goto bad_offset;

        }

        break;

    case 0xdd8: /* SAU_RNR */

        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            goto bad_offset;

        }

        if (!attrs.secure) {

            return;

        }

        if (value >= cpu->sau_sregion) {

            qemu_log_mask(LOG_GUEST_ERROR, "SAU region out of range %"

                          PRIu32 "/%" PRIu32 "\n",

                          value, cpu->sau_sregion);

        } else {

            cpu->env.sau.rnr = value;

        }

        break;

    case 0xddc: /* SAU_RBAR */

    {

        int region = cpu->env.sau.rnr;

        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            goto bad_offset;

        }

        if (!attrs.secure) {

            return;

        }

        if (region >= cpu->sau_sregion) {

            return;

        }

        cpu->env.sau.rbar[region] = value & ~0x1f;

        tlb_flush(CPU(cpu));

        break;

    }

    case 0xde0: /* SAU_RLAR */

    {

        int region = cpu->env.sau.rnr;

        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            goto bad_offset;

        }

        if (!attrs.secure) {

            return;

        }

        if (region >= cpu->sau_sregion) {

            return;

        }

        cpu->env.sau.rlar[region] = value & ~0x1c;

        tlb_flush(CPU(cpu));

        break;

    }

    case 0xde4: /* SFSR */

        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            goto bad_offset;

        }

        if (!attrs.secure) {

            return;

        }

        cpu->env.v7m.sfsr &= ~value; /* W1C */

        break;

    case 0xde8: /* SFAR */

        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            goto bad_offset;

        }

        if (!attrs.secure) {

            return;

        }

        cpu->env.v7m.sfsr = value;

        break;

    case 0xf00: /* Software Triggered Interrupt Register */

    {

        int excnum = (value & 0x1ff) + NVIC_FIRST_IRQ;

        if (excnum < s->num_irq) {

            armv7m_nvic_set_pending(s, excnum, false);

        }

        break;

    }

    default:

    bad_offset:

        qemu_log_mask(LOG_GUEST_ERROR,

                      "NVIC: Bad write offset 0x%x\n", offset);

    }

}


static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,

                                target_ulong tce)

{

    sPAPRTCE *tcep;

    if (ioba >= tcet->window_size) {

        hcall_dprintf("spapr_vio_put_tce on out-of-boards IOBA 0x"

                      TARGET_FMT_lx "\n", ioba);

        return H_PARAMETER;

    }

    tcep = tcet->table + (ioba >> SPAPR_TCE_PAGE_SHIFT);

    tcep->tce = tce;

    return H_SUCCESS;

}


static void gen_lq(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    int ra, rd;

    TCGv EA;

    /* Restore CPU state */

    if (unlikely(ctx->mem_idx == 0)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    ra = rA(ctx->opcode);

    rd = rD(ctx->opcode);

    if (unlikely((rd & 1) || rd == ra)) {

        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);

        return;

    }

    if (unlikely(ctx->le_mode)) {

        /* Little-endian mode is not handled */

        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);

        return;

    }

    gen_set_access_type(ctx, ACCESS_INT);

    EA = tcg_temp_new();

    gen_addr_imm_index(ctx, EA, 0x0F);

    gen_qemu_ld64(ctx, cpu_gpr[rd], EA);

    gen_addr_add(ctx, EA, EA, 8);

    gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);

    tcg_temp_free(EA);

#endif

}


static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)

{

    ESPState *s = opaque;

    uint32_t saddr;

    saddr = (addr >> s->it_shift) & (ESP_REGS - 1);

    DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]);

    switch (saddr) {

    case ESP_FIFO:

        if (s->ti_size > 0) {

            s->ti_size--;

            if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {

                /* Data in/out.  */

                fprintf(stderr, "esp: PIO data read not implemented\n");

                s->rregs[ESP_FIFO] = 0;

            } else {

                s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];

            }

            esp_raise_irq(s);

        }

        if (s->ti_size == 0) {

            s->ti_rptr = 0;

            s->ti_wptr = 0;

        }

        break;

    case ESP_RINTR:

        // Clear interrupt/error status bits

        s->rregs[ESP_RSTAT] &= ~(STAT_GE | STAT_PE);

        esp_lower_irq(s);

        break;

    default:

        break;

    }

    return s->rregs[saddr];

}


int av_vsrc_buffer_add_frame2(AVFilterContext *buffer_filter, AVFrame *frame,

                              int64_t pts, AVRational pixel_aspect, int width,

                              int height, enum PixelFormat  pix_fmt,

                              const char *sws_param)

{

    BufferSourceContext *c = buffer_filter->priv;

    int ret;

    if (c->has_frame) {

        av_log(buffer_filter, AV_LOG_ERROR,

               "Buffering several frames is not supported. "

               "Please consume all available frames before adding a new one.\n"

            );

        //return -1;

    }

    if(width != c->w || height != c->h || pix_fmt != c->pix_fmt){

        AVFilterContext *scale= buffer_filter->outputs[0]->dst;

        AVFilterLink *link;

        av_log(buffer_filter, AV_LOG_INFO, "Changing filter graph input to accept %dx%d %d (%d %d)\n",

               width,height,pix_fmt, c->pix_fmt, scale->outputs[0]->format);

        if(!scale || strcmp(scale->filter->name,"scale")){

            AVFilter *f= avfilter_get_by_name("scale");

            av_log(buffer_filter, AV_LOG_INFO, "Inserting scaler filter\n");

            if(avfilter_open(&scale, f, "Input equalizer") < 0)

                return -1;

            if((ret=avfilter_init_filter(scale, sws_param, NULL))<0){

                avfilter_free(scale);

                return ret;

            }

            if((ret=avfilter_insert_filter(buffer_filter->outputs[0], scale, 0, 0))<0){

                avfilter_free(scale);

                return ret;

            }

            scale->outputs[0]->format= c->pix_fmt;

        }

        c->pix_fmt= scale->inputs[0]->format= pix_fmt;

        c->w= scale->inputs[0]->w= width;

        c->h= scale->inputs[0]->h= height;

        link= scale->outputs[0];

        if ((ret =  link->srcpad->config_props(link)) < 0)

            return ret;

    }

    memcpy(c->frame.data    , frame->data    , sizeof(frame->data));

    memcpy(c->frame.linesize, frame->linesize, sizeof(frame->linesize));

    c->frame.interlaced_frame= frame->interlaced_frame;

    c->frame.top_field_first = frame->top_field_first;

    c->frame.key_frame = frame->key_frame;

    c->frame.pict_type = frame->pict_type;

    c->pts = pts;

    c->pixel_aspect = pixel_aspect;

    c->has_frame = 1;

    return 0;

}


static void pcie_cap_slot_hotplug_common(PCIDevice *hotplug_dev,

                                         DeviceState *dev,

                                         uint8_t **exp_cap, Error **errp)

{

    *exp_cap = hotplug_dev->config + hotplug_dev->exp.exp_cap;

    uint16_t sltsta = pci_get_word(*exp_cap + PCI_EXP_SLTSTA);

    PCIE_DEV_PRINTF(PCI_DEVICE(dev), "hotplug state: 0x%x\n", sltsta);

    if (sltsta & PCI_EXP_SLTSTA_EIS) {

        /* the slot is electromechanically locked.

         * This error is propagated up to qdev and then to HMP/QMP.

         */

        error_setg_errno(errp, -EBUSY, "slot is electromechanically locked");

    }

}


void qmp_getfd(const char *fdname, Error **errp)

{

    mon_fd_t *monfd;

    int fd;

    fd = qemu_chr_fe_get_msgfd(cur_mon->chr);

    if (fd == -1) {

        error_set(errp, QERR_FD_NOT_SUPPLIED);

        return;

    }

    if (qemu_isdigit(fdname[0])) {

        error_set(errp, QERR_INVALID_PARAMETER_VALUE, "fdname",

                  "a name not starting with a digit");

        return;

    }

    QLIST_FOREACH(monfd, &cur_mon->fds, next) {

        if (strcmp(monfd->name, fdname) != 0) {

            continue;

        }

        close(monfd->fd);

        monfd->fd = fd;

        return;

    }

    monfd = g_malloc0(sizeof(mon_fd_t));

    monfd->name = g_strdup(fdname);

    monfd->fd = fd;

    QLIST_INSERT_HEAD(&cur_mon->fds, monfd, next);

}


static void qmp_deserialize(void **native_out, void *datap,

                            VisitorFunc visit, Error **errp)

{

    QmpSerializeData *d = datap;

    QString *output_json = qobject_to_json(qmp_output_get_qobject(d->qov));

    QObject *obj = qobject_from_json(qstring_get_str(output_json));

    QDECREF(output_json);

    d->qiv = qmp_input_visitor_new(obj);

    qobject_decref(obj);

    visit(qmp_input_get_visitor(d->qiv), native_out, errp);

}


static bool coroutine_fn yield_and_check(BackupBlockJob *job)

{

    if (block_job_is_cancelled(&job->common)) {

        return true;

    }

    /* we need to yield so that bdrv_drain_all() returns.

     * (without, VM does not reboot)

     */

    if (job->common.speed) {

        uint64_t delay_ns = ratelimit_calculate_delay(&job->limit,

                                                      job->sectors_read);

        job->sectors_read = 0;

        block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, delay_ns);

    } else {

        block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, 0);

    }

    if (block_job_is_cancelled(&job->common)) {

        return true;

    }

    return false;

}


static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)

{

    SCSIDevice *d = virtio_scsi_device_find(s, req->req.tmf.lun);

    SCSIRequest *r, *next;

    BusChild *kid;

    int target;

    int ret = 0;

    if (s->dataplane_started) {

        assert(blk_get_aio_context(d->conf.blk) == s->ctx);

    }

    /* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE".  */

    req->resp.tmf.response = VIRTIO_SCSI_S_OK;

    virtio_tswap32s(VIRTIO_DEVICE(s), &req->req.tmf.subtype);

    switch (req->req.tmf.subtype) {

    case VIRTIO_SCSI_T_TMF_ABORT_TASK:

    case VIRTIO_SCSI_T_TMF_QUERY_TASK:

        if (!d) {

            goto fail;

        }

        if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) {

            goto incorrect_lun;

        }

        QTAILQ_FOREACH_SAFE(r, &d->requests, next, next) {

            VirtIOSCSIReq *cmd_req = r->hba_private;

            if (cmd_req && cmd_req->req.cmd.tag == req->req.tmf.tag) {

                break;

            }

        }

        if (r) {

            /*

             * Assert that the request has not been completed yet, we

             * check for it in the loop above.

             */

            assert(r->hba_private);

            if (req->req.tmf.subtype == VIRTIO_SCSI_T_TMF_QUERY_TASK) {

                /* "If the specified command is present in the task set, then

                 * return a service response set to FUNCTION SUCCEEDED".

                 */

                req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED;

            } else {

                VirtIOSCSICancelNotifier *notifier;

                req->remaining = 1;

                notifier = g_new(VirtIOSCSICancelNotifier, 1);

                notifier->tmf_req = req;

                notifier->notifier.notify = virtio_scsi_cancel_notify;

                scsi_req_cancel_async(r, &notifier->notifier);

                ret = -EINPROGRESS;

            }

        }

        break;

    case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET:

        if (!d) {

            goto fail;

        }

        if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) {

            goto incorrect_lun;

        }

        s->resetting++;

        qdev_reset_all(&d->qdev);

        s->resetting--;

        break;

    case VIRTIO_SCSI_T_TMF_ABORT_TASK_SET:

    case VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET:

    case VIRTIO_SCSI_T_TMF_QUERY_TASK_SET:

        if (!d) {

            goto fail;

        }

        if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) {

            goto incorrect_lun;

        }

        /* Add 1 to "remaining" until virtio_scsi_do_tmf returns.

         * This way, if the bus starts calling back to the notifiers

         * even before we finish the loop, virtio_scsi_cancel_notify

         * will not complete the TMF too early.

         */

        req->remaining = 1;

        QTAILQ_FOREACH_SAFE(r, &d->requests, next, next) {

            if (r->hba_private) {

                if (req->req.tmf.subtype == VIRTIO_SCSI_T_TMF_QUERY_TASK_SET) {

                    /* "If there is any command present in the task set, then

                     * return a service response set to FUNCTION SUCCEEDED".

                     */

                    req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED;

                    break;

                } else {

                    VirtIOSCSICancelNotifier *notifier;

                    req->remaining++;

                    notifier = g_new(VirtIOSCSICancelNotifier, 1);

                    notifier->notifier.notify = virtio_scsi_cancel_notify;

                    notifier->tmf_req = req;

                    scsi_req_cancel_async(r, &notifier->notifier);

                }

            }

        }

        if (--req->remaining > 0) {

            ret = -EINPROGRESS;

        }

        break;

    case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:

        target = req->req.tmf.lun[1];

        s->resetting++;

        QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {

             d = DO_UPCAST(SCSIDevice, qdev, kid->child);

             if (d->channel == 0 && d->id == target) {

                qdev_reset_all(&d->qdev);

             }

        }

        s->resetting--;

        break;

    case VIRTIO_SCSI_T_TMF_CLEAR_ACA:

    default:

        req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_REJECTED;

        break;

    }

    return ret;

incorrect_lun:

    req->resp.tmf.response = VIRTIO_SCSI_S_INCORRECT_LUN;

    return ret;

fail:

    req->resp.tmf.response = VIRTIO_SCSI_S_BAD_TARGET;

    return ret;

}


int ffurl_read_complete(URLContext *h, unsigned char *buf, int size)

{

    if (h->flags & AVIO_FLAG_WRITE)

        return AVERROR(EIO);

    return retry_transfer_wrapper(h, buf, size, size, h->prot->url_read);

}


int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries,

                            uint8_t bar_nr)

{

    int ret;

    char *name;

    uint32_t bar_size = 4096;

    uint32_t bar_pba_offset = bar_size / 2;

    uint32_t bar_pba_size = (nentries / 8 + 1) * 8;

    /*

     * Migration compatibility dictates that this remains a 4k

     * BAR with the vector table in the lower half and PBA in

     * the upper half for nentries which is lower or equal to 128.

     * No need to care about using more than 65 entries for legacy

     * machine types who has at most 64 queues.

     */

    if (nentries * PCI_MSIX_ENTRY_SIZE > bar_pba_offset) {

        bar_pba_offset = nentries * PCI_MSIX_ENTRY_SIZE;

    }

    if (bar_pba_offset + bar_pba_size > 4096) {

        bar_size = bar_pba_offset + bar_pba_size;

    }

    if (bar_size & (bar_size - 1)) {

        bar_size = 1 << qemu_fls(bar_size);

    }

    name = g_strdup_printf("%s-msix", dev->name);

    memory_region_init(&dev->msix_exclusive_bar, OBJECT(dev), name, bar_size);

    g_free(name);

    ret = msix_init(dev, nentries, &dev->msix_exclusive_bar, bar_nr,

                    0, &dev->msix_exclusive_bar,

                    bar_nr, bar_pba_offset,

                    0);

    if (ret) {

        return ret;

    }

    pci_register_bar(dev, bar_nr, PCI_BASE_ADDRESS_SPACE_MEMORY,

                     &dev->msix_exclusive_bar);

    return 0;

}


void qemu_del_timer(QEMUTimer *ts)

{

}


static void restore_native_fp_frstor(CPUState *env)

{

    int fptag, i, j;

    struct fpstate fp1, *fp = &fp1;

    fp->fpuc = env->fpuc;

    fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;

    fptag = 0;

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

	fptag <<= 2;

	if (env->fptags[i]) {

            fptag |= 3;

        } else {

            /* the FPU automatically computes it */

        }

    }

    fp->fptag = fptag;

    j = env->fpstt;

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

        memcpy(&fp->fpregs1[i * 10], &env->fpregs[j].d, 10);

        j = (j + 1) & 7;

    }

    asm volatile ("frstor %0" : "=m" (*fp));

}


static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb)

{

    unsigned long next_tb;

    TranslationBlock *tb;

    /* Should never happen.

       We only end up here when an existing TB is too long.  */

    if (max_cycles > CF_COUNT_MASK)

        max_cycles = CF_COUNT_MASK;

    tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,

                     max_cycles);

    env->current_tb = tb;

    /* execute the generated code */

    next_tb = tcg_qemu_tb_exec(tb->tc_ptr);

    env->current_tb = NULL;

    if ((next_tb & 3) == 2) {

        /* Restore PC.  This may happen if async event occurs before

           the TB starts executing.  */

        cpu_pc_from_tb(env, tb);

    }

    tb_phys_invalidate(tb, -1);

    tb_free(tb);

}


static char *regname(uint32_t addr)

{

    static char buf[16];

    if (addr < PCI_IO_SIZE) {

        const char *r = reg[addr / 4];

        if (r != 0) {

            sprintf(buf, "%s+%u", r, addr % 4);

        } else {

            sprintf(buf, "0x%02x", addr);

        }

    } else {

        sprintf(buf, "??? 0x%08x", addr);

    }

    return buf;

}


static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,

                                   bool is_scalar, bool is_u, bool is_q,

                                   int size, int rn, int rd)

{

    bool is_double = (size == 3);

    TCGv_ptr fpst = get_fpstatus_ptr();

    if (is_double) {

        TCGv_i64 tcg_op = tcg_temp_new_i64();

        TCGv_i64 tcg_zero = tcg_const_i64(0);

        TCGv_i64 tcg_res = tcg_temp_new_i64();

        NeonGenTwoDoubleOPFn *genfn;

        bool swap = false;

        int pass;

        switch (opcode) {

        case 0x2e: /* FCMLT (zero) */

            swap = true;

            /* fallthrough */

        case 0x2c: /* FCMGT (zero) */

            genfn = gen_helper_neon_cgt_f64;

            break;

        case 0x2d: /* FCMEQ (zero) */

            genfn = gen_helper_neon_ceq_f64;

            break;

        case 0x6d: /* FCMLE (zero) */

            swap = true;

            /* fall through */

        case 0x6c: /* FCMGE (zero) */

            genfn = gen_helper_neon_cge_f64;

            break;

        default:

            g_assert_not_reached();

        }

        for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {

            read_vec_element(s, tcg_op, rn, pass, MO_64);

            if (swap) {

                genfn(tcg_res, tcg_zero, tcg_op, fpst);

            } else {

                genfn(tcg_res, tcg_op, tcg_zero, fpst);

            }

            write_vec_element(s, tcg_res, rd, pass, MO_64);

        }

        if (is_scalar) {

            clear_vec_high(s, rd);

        }

        tcg_temp_free_i64(tcg_res);

        tcg_temp_free_i64(tcg_zero);

        tcg_temp_free_i64(tcg_op);

    } else {

        TCGv_i32 tcg_op = tcg_temp_new_i32();

        TCGv_i32 tcg_zero = tcg_const_i32(0);

        TCGv_i32 tcg_res = tcg_temp_new_i32();

        NeonGenTwoSingleOPFn *genfn;

        bool swap = false;

        int pass, maxpasses;

        switch (opcode) {

        case 0x2e: /* FCMLT (zero) */

            swap = true;

            /* fall through */

        case 0x2c: /* FCMGT (zero) */

            genfn = gen_helper_neon_cgt_f32;

            break;

        case 0x2d: /* FCMEQ (zero) */

            genfn = gen_helper_neon_ceq_f32;

            break;

        case 0x6d: /* FCMLE (zero) */

            swap = true;

            /* fall through */

        case 0x6c: /* FCMGE (zero) */

            genfn = gen_helper_neon_cge_f32;

            break;

        default:

            g_assert_not_reached();

        }

        if (is_scalar) {

            maxpasses = 1;

        } else {

            maxpasses = is_q ? 4 : 2;

        }

        for (pass = 0; pass < maxpasses; pass++) {

            read_vec_element_i32(s, tcg_op, rn, pass, MO_32);

            if (swap) {

                genfn(tcg_res, tcg_zero, tcg_op, fpst);

            } else {

                genfn(tcg_res, tcg_op, tcg_zero, fpst);

            }

            if (is_scalar) {

                write_fp_sreg(s, rd, tcg_res);

            } else {

                write_vec_element_i32(s, tcg_res, rd, pass, MO_32);

            }

        }

        tcg_temp_free_i32(tcg_res);

        tcg_temp_free_i32(tcg_zero);

        tcg_temp_free_i32(tcg_op);

        if (!is_q && !is_scalar) {

            clear_vec_high(s, rd);

        }

    }

    tcg_temp_free_ptr(fpst);

}


static int on2avc_decode_band_scales(On2AVCContext *c, GetBitContext *gb)

{

    int w, w2, b, scale, first = 1;

    int band_off = 0;

    for (w = 0; w < c->num_windows; w++) {

        if (!c->grouping[w]) {

            memcpy(c->band_scales + band_off,

                   c->band_scales + band_off - c->num_bands,

                   c->num_bands * sizeof(*c->band_scales));

            band_off += c->num_bands;

            continue;

        }

        for (b = 0; b < c->num_bands; b++) {

            if (!c->band_type[band_off]) {

                int all_zero = 1;

                for (w2 = w + 1; w2 < c->num_windows; w2++) {

                    if (c->grouping[w2])

                        break;

                    if (c->band_type[w2 * c->num_bands + b]) {

                        all_zero = 0;

                        break;

                    }

                }

                if (all_zero) {

                    c->band_scales[band_off++] = 0;

                    continue;

                }

            }

            if (first) {

                scale = get_bits(gb, 7);

                first = 0;

            } else {

                scale += get_vlc2(gb, c->scale_diff.table, 9, 3) - 60;

            }

            if (scale < 0 || scale > 128) {

                av_log(c->avctx, AV_LOG_ERROR, "Invalid scale value %d\n",

                       scale);

                return AVERROR_INVALIDDATA;

            }

            c->band_scales[band_off++] = c->scale_tab[scale];

        }

    }

    return 0;

}


static inline void writer_print_rational(WriterContext *wctx,

                                         const char *key, AVRational q, char sep)

{

    AVBPrint buf;

    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);

    av_bprintf(&buf, "%d%c%d", q.num, sep, q.den);

    wctx->writer->print_string(wctx, key, buf.str);

    wctx->nb_item++;

}


int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len,

                          int flags, CPUWatchpoint **watchpoint)

{

    target_ulong len_mask = ~(len - 1);

    CPUWatchpoint *wp;

    /* sanity checks: allow power-of-2 lengths, deny unaligned watchpoints */

    if ((len != 1 && len != 2 && len != 4 && len != 8) || (addr & ~len_mask)) {

        fprintf(stderr, "qemu: tried to set invalid watchpoint at "

                TARGET_FMT_lx ", len=" TARGET_FMT_lu "\n", addr, len);

        return -EINVAL;

    }

    wp = qemu_malloc(sizeof(*wp));

    wp->vaddr = addr;

    wp->len_mask = len_mask;

    wp->flags = flags;

    /* keep all GDB-injected watchpoints in front */

    if (flags & BP_GDB)

        TAILQ_INSERT_HEAD(&env->watchpoints, wp, entry);

    else

        TAILQ_INSERT_TAIL(&env->watchpoints, wp, entry);

    tlb_flush_page(env, addr);

    if (watchpoint)

        *watchpoint = wp;

    return 0;

}


static off_t read_off(int fd, int64_t offset)

{

	uint64_t buffer;

	if (pread(fd, &buffer, 8, offset) < 8)

		return 0;

	return be64_to_cpu(buffer);

}


void pc_machine_done(Notifier *notifier, void *data)

{

    PCMachineState *pcms = container_of(notifier,

                                        PCMachineState, machine_done);

    PCIBus *bus = pcms->bus;

    /* set the number of CPUs */

    rtc_set_cpus_count(pcms->rtc, pcms->boot_cpus);

    if (bus) {

        int extra_hosts = 0;

        QLIST_FOREACH(bus, &bus->child, sibling) {

            /* look for expander root buses */

            if (pci_bus_is_root(bus)) {

                extra_hosts++;

            }

        }

        if (extra_hosts && pcms->fw_cfg) {

            uint64_t *val = g_malloc(sizeof(*val));

            *val = cpu_to_le64(extra_hosts);

            fw_cfg_add_file(pcms->fw_cfg,

                    "etc/extra-pci-roots", val, sizeof(*val));

        }

    }

    acpi_setup();

    if (pcms->fw_cfg) {

        pc_build_smbios(pcms);

        pc_build_feature_control_file(pcms);

        /* update FW_CFG_NB_CPUS to account for -device added CPUs */

        fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus);

    }

    if (pcms->apic_id_limit > 255) {

        IntelIOMMUState *iommu = INTEL_IOMMU_DEVICE(x86_iommu_get_default());

        if (!iommu || !iommu->x86_iommu.intr_supported ||

            iommu->intr_eim != ON_OFF_AUTO_ON) {

            error_report("current -smp configuration requires "

                         "Extended Interrupt Mode enabled. "

                         "You can add an IOMMU using: "

                         "-device intel-iommu,intremap=on,eim=on");

            exit(EXIT_FAILURE);

        }

    }

}


static void spapr_machine_reset(void)

{

    MachineState *machine = MACHINE(qdev_get_machine());

    sPAPRMachineState *spapr = SPAPR_MACHINE(machine);

    PowerPCCPU *first_ppc_cpu;

    uint32_t rtas_limit;

    hwaddr rtas_addr, fdt_addr;

    void *fdt;

    int rc;

    /* Check for unknown sysbus devices */

    foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);

    spapr_caps_reset(spapr);

    first_ppc_cpu = POWERPC_CPU(first_cpu);

    if (kvm_enabled() && kvmppc_has_cap_mmu_radix() &&

        ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,

                         spapr->max_compat_pvr)) {

        /* If using KVM with radix mode available, VCPUs can be started

         * without a HPT because KVM will start them in radix mode.

         * Set the GR bit in PATB so that we know there is no HPT. */

        spapr->patb_entry = PATBE1_GR;

    } else {

        spapr_setup_hpt_and_vrma(spapr);

    }

    qemu_devices_reset();

    /* DRC reset may cause a device to be unplugged. This will cause troubles

     * if this device is used by another device (eg, a running vhost backend

     * will crash QEMU if the DIMM holding the vring goes away). To avoid such

     * situations, we reset DRCs after all devices have been reset.

     */

    object_child_foreach_recursive(object_get_root(), spapr_reset_drcs, NULL);

    spapr_clear_pending_events(spapr);

    /*

     * We place the device tree and RTAS just below either the top of the RMA,

     * or just below 2GB, whichever is lowere, so that it can be

     * processed with 32-bit real mode code if necessary

     */

    rtas_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR);

    rtas_addr = rtas_limit - RTAS_MAX_SIZE;

    fdt_addr = rtas_addr - FDT_MAX_SIZE;

    /* if this reset wasn't generated by CAS, we should reset our

     * negotiated options and start from scratch */

    if (!spapr->cas_reboot) {

        spapr_ovec_cleanup(spapr->ov5_cas);

        spapr->ov5_cas = spapr_ovec_new();

        ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal);

    }

    fdt = spapr_build_fdt(spapr, rtas_addr, spapr->rtas_size);

    spapr_load_rtas(spapr, fdt, rtas_addr);

    rc = fdt_pack(fdt);

    /* Should only fail if we've built a corrupted tree */

    assert(rc == 0);

    if (fdt_totalsize(fdt) > FDT_MAX_SIZE) {

        error_report("FDT too big ! 0x%x bytes (max is 0x%x)",

                     fdt_totalsize(fdt), FDT_MAX_SIZE);

        exit(1);

    }

    /* Load the fdt */

    qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));

    cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));

    g_free(fdt);

    /* Set up the entry state */

    first_ppc_cpu->env.gpr[3] = fdt_addr;

    first_ppc_cpu->env.gpr[5] = 0;

    first_cpu->halted = 0;

    first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT;

    spapr->cas_reboot = false;

}


bool replay_next_event_is(int event)

{

    bool res = false;

    /* nothing to skip - not all instructions used */

    if (replay_state.instructions_count != 0) {

        assert(replay_data_kind == EVENT_INSTRUCTION);

        return event == EVENT_INSTRUCTION;

    }

    while (true) {

        if (event == replay_data_kind) {

            res = true;

        }

        switch (replay_data_kind) {

        case EVENT_SHUTDOWN:

            replay_finish_event();

            qemu_system_shutdown_request();

            break;

        default:

            /* clock, time_t, checkpoint and other events */

            return res;

        }

    }

    return res;

}


void kvm_init_irq_routing(KVMState *s)

{

    int gsi_count, i;

    gsi_count = kvm_check_extension(s, KVM_CAP_IRQ_ROUTING);

    if (gsi_count > 0) {

        unsigned int gsi_bits, i;

        /* Round up so we can search ints using ffs */

        gsi_bits = ALIGN(gsi_count, 32);

        s->used_gsi_bitmap = g_malloc0(gsi_bits / 8);

        s->gsi_count = gsi_count;

        /* Mark any over-allocated bits as already in use */

        for (i = gsi_count; i < gsi_bits; i++) {

            set_gsi(s, i);

        }

    }

    s->irq_routes = g_malloc0(sizeof(*s->irq_routes));

    s->nr_allocated_irq_routes = 0;

    if (!s->direct_msi) {

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

            QTAILQ_INIT(&s->msi_hashtab[i]);

        }

    }

    kvm_arch_init_irq_routing(s);

}


static uint16_t *phys_page_find_alloc(target_phys_addr_t index, int alloc)

{

    PhysPageEntry *lp, *p;

    int i, j;

    lp = &phys_map;

    /* Level 1..N.  */

    for (i = P_L2_LEVELS - 1; i >= 0; i--) {

        if (lp->u.node == NULL) {

            if (!alloc) {

                return NULL;

            }

            lp->u.node = p = g_malloc0(sizeof(PhysPageEntry) * L2_SIZE);

            if (i == 0) {

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

                    p[j].u.leaf = phys_section_unassigned;

                }

            }

        }

        lp = &lp->u.node[(index >> (i * L2_BITS)) & (L2_SIZE - 1)];

    }

    return &lp->u.leaf;

}


void qemu_cpu_kick(void *_env)

{

    CPUState *env = _env;

    qemu_cond_broadcast(env->halt_cond);

    if (!env->thread_kicked) {

        qemu_cpu_kick_thread(env);

        env->thread_kicked = true;

    }

}


static int http_proxy_open(URLContext *h, const char *uri, int flags)

{

    HTTPContext *s = h->priv_data;

    char hostname[1024], hoststr[1024];

    char auth[1024], pathbuf[1024], *path;

    char lower_url[100];

    int port, ret = 0, attempts = 0;

    HTTPAuthType cur_auth_type;

    char *authstr;

    int new_loc;

    h->is_streamed = 1;

    av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port,

                 pathbuf, sizeof(pathbuf), uri);

    ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);

    path = pathbuf;

    if (*path == '/')

        path++;

    ff_url_join(lower_url, sizeof(lower_url), "tcp", NULL, hostname, port,

                NULL);

redo:

    ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE,

                     &h->interrupt_callback, NULL);

    if (ret < 0)

        return ret;

    authstr = ff_http_auth_create_response(&s->proxy_auth_state, auth,

                                           path, "CONNECT");

    snprintf(s->buffer, sizeof(s->buffer),

             "CONNECT %s HTTP/1.1\r\n"

             "Host: %s\r\n"

             "Connection: close\r\n"

             "%s%s"

             "\r\n",

             path,

             hoststr,

             authstr ? "Proxy-" : "", authstr ? authstr : "");

    av_freep(&authstr);

    if ((ret = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0)

        goto fail;

    s->buf_ptr = s->buffer;

    s->buf_end = s->buffer;

    s->line_count = 0;

    s->filesize = -1;

    cur_auth_type = s->proxy_auth_state.auth_type;

    /* Note: This uses buffering, potentially reading more than the

     * HTTP header. If tunneling a protocol where the server starts

     * the conversation, we might buffer part of that here, too.

     * Reading that requires using the proper ffurl_read() function

     * on this URLContext, not using the fd directly (as the tls

     * protocol does). This shouldn't be an issue for tls though,

     * since the client starts the conversation there, so there

     * is no extra data that we might buffer up here.

     */

    ret = http_read_header(h, &new_loc);

    if (ret < 0)

        goto fail;

    attempts++;

    if (s->http_code == 407 &&

        (cur_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) &&

        s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 2) {

        ffurl_closep(&s->hd);

        goto redo;

    }

    if (s->http_code < 400)

        return 0;

    ret = AVERROR(EIO);

fail:

    http_proxy_close(h);

    return ret;

}


static int get_physical_address_data(CPUState *env,

                                     target_phys_addr_t *physical, int *prot,

                                     target_ulong address, int rw, int is_user)

{

    target_ulong mask;

    unsigned int i;

    if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */

        *physical = address;

        *prot = PAGE_READ | PAGE_WRITE;

        return 0;

    }

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

        switch ((env->dtlb_tte[i] >> 61) & 3) {

        default:

        case 0x0: // 8k

            mask = 0xffffffffffffe000ULL;

            break;

        case 0x1: // 64k

            mask = 0xffffffffffff0000ULL;

            break;

        case 0x2: // 512k

            mask = 0xfffffffffff80000ULL;

            break;

        case 0x3: // 4M

            mask = 0xffffffffffc00000ULL;

            break;

        }

        // ctx match, vaddr match, valid?

        if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&

            (address & mask) == (env->dtlb_tag[i] & mask) &&

            (env->dtlb_tte[i] & 0x8000000000000000ULL)) {

            // access ok?

            if (((env->dtlb_tte[i] & 0x4) && is_user) ||

                (!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {

                if (env->dmmuregs[3]) /* Fault status register */

                    env->dmmuregs[3] = 2; /* overflow (not read before

                                             another fault) */

                env->dmmuregs[3] |= (is_user << 3) | ((rw == 1) << 2) | 1;

                env->dmmuregs[4] = address; /* Fault address register */

                env->exception_index = TT_DFAULT;

#ifdef DEBUG_MMU

                printf("DFAULT at 0x%" PRIx64 "\n", address);

#endif

                return 1;

            }

            *physical = ((env->dtlb_tte[i] & mask) | (address & ~mask)) &

                        0x1ffffffe000ULL;

            *prot = PAGE_READ;

            if (env->dtlb_tte[i] & 0x2)

                *prot |= PAGE_WRITE;

            return 0;

        }

    }

#ifdef DEBUG_MMU

    printf("DMISS at 0x%" PRIx64 "\n", address);

#endif

    env->dmmuregs[6] = (address & ~0x1fffULL) | (env->dmmuregs[1] & 0x1fff);

    env->exception_index = TT_DMISS;

    return 1;

}


static int local_create_mapped_attr_dir(FsContext *ctx, const char *path)

{

    int err;

    char attr_dir[PATH_MAX];

    char *tmp_path = g_strdup(path);

    snprintf(attr_dir, PATH_MAX, "%s/%s/%s",

             ctx->fs_root, dirname(tmp_path), VIRTFS_META_DIR);

    err = mkdir(attr_dir, 0700);

    if (err < 0 && errno == EEXIST) {

        err = 0;

    }

    g_free(tmp_path);

    return err;

}


static inline void sync_jmpstate(DisasContext *dc)

{

    if (dc->jmp == JMP_DIRECT) {

            dc->jmp = JMP_INDIRECT;

            tcg_gen_movi_tl(env_btaken, 1);

            tcg_gen_movi_tl(env_btarget, dc->jmp_pc);

    }

}


void register_device_unmigratable(DeviceState *dev, const char *idstr,

                                                            void *opaque)

{

    SaveStateEntry *se;

    char id[256] = "";

    if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {

        char *path = dev->parent_bus->info->get_dev_path(dev);

        if (path) {

            pstrcpy(id, sizeof(id), path);

            pstrcat(id, sizeof(id), "/");

            g_free(path);

        }

    }

    pstrcat(id, sizeof(id), idstr);

    QTAILQ_FOREACH(se, &savevm_handlers, entry) {

        if (strcmp(se->idstr, id) == 0 && se->opaque == opaque) {

            se->no_migrate = 1;

        }

    }

}


int css_do_rsch(SubchDev *sch)

{

    SCSW *s = &sch->curr_status.scsw;

    PMCW *p = &sch->curr_status.pmcw;

    int ret;

    if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {

        ret = -ENODEV;

        goto out;

    }

    if (s->ctrl & SCSW_STCTL_STATUS_PEND) {

        ret = -EINPROGRESS;

        goto out;

    }

    if (((s->ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||

        (s->ctrl & SCSW_ACTL_RESUME_PEND) ||

        (!(s->ctrl & SCSW_ACTL_SUSP))) {

        ret = -EINVAL;

        goto out;

    }

    /* If monitoring is active, update counter. */

    if (channel_subsys.chnmon_active) {

        css_update_chnmon(sch);

    }

    s->ctrl |= SCSW_ACTL_RESUME_PEND;

    do_subchannel_work(sch, NULL);

    ret = 0;

out:

    return ret;

}


CPUState *cpu_copy(CPUState *env)

{

    CPUState *new_env = cpu_init(env->cpu_model_str);

    CPUState *next_cpu = new_env->next_cpu;

    int cpu_index = new_env->cpu_index;

#if defined(TARGET_HAS_ICE)

    CPUBreakpoint *bp;

    CPUWatchpoint *wp;

#endif

    memcpy(new_env, env, sizeof(CPUState));

    /* Preserve chaining and index. */

    new_env->next_cpu = next_cpu;

    new_env->cpu_index = cpu_index;

    /* Clone all break/watchpoints.

       Note: Once we support ptrace with hw-debug register access, make sure

       BP_CPU break/watchpoints are handled correctly on clone. */

    TAILQ_INIT(&env->breakpoints);

    TAILQ_INIT(&env->watchpoints);

#if defined(TARGET_HAS_ICE)

    TAILQ_FOREACH(bp, &env->breakpoints, entry) {

        cpu_breakpoint_insert(new_env, bp->pc, bp->flags, NULL);

    }

    TAILQ_FOREACH(wp, &env->watchpoints, entry) {

        cpu_watchpoint_insert(new_env, wp->vaddr, (~wp->len_mask) + 1,

                              wp->flags, NULL);

    }

#endif

    return new_env;

}


xilinx_axidma_data_stream_push(StreamSlave *obj, unsigned char *buf, size_t len,

                               uint32_t *app)

{

    XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(obj);

    struct Stream *s = &ds->dma->streams[1];

    size_t ret;

    if (!app) {

        hw_error("No stream app data!\n");

    }

    ret = stream_process_s2mem(s, buf, len, app);

    stream_update_irq(s);

    return ret;

}


void *av_realloc(void *ptr, unsigned int size)

{

#ifdef MEMALIGN_HACK

    int diff;

#endif

    /* let's disallow possible ambiguous cases */

    if(size > INT_MAX)

        return NULL;

#ifdef MEMALIGN_HACK

    //FIXME this isn't aligned correctly, though it probably isn't needed

    if(!ptr) return av_malloc(size);

    diff= ((char*)ptr)[-1];

    return realloc(ptr - diff, size + diff) + diff;

#else

    return realloc(ptr, size);

#endif

}


static int mmf_probe(AVProbeData *p)

{

    /* check file header */

    if (p->buf_size <= 32)

        return 0;

    if (p->buf[0] == 'M' && p->buf[1] == 'M' &&

        p->buf[2] == 'M' && p->buf[3] == 'D' &&

        p->buf[8] == 'C' && p->buf[9] == 'N' &&

        p->buf[10] == 'T' && p->buf[11] == 'I')

        return AVPROBE_SCORE_MAX;

    else

        return 0;

}


static XICSState *try_create_xics(const char *type, int nr_servers,

                                  int nr_irqs)

{

    DeviceState *dev;

    dev = qdev_create(NULL, type);

    qdev_prop_set_uint32(dev, "nr_servers", nr_servers);

    qdev_prop_set_uint32(dev, "nr_irqs", nr_irqs);

    if (qdev_init(dev) < 0) {

        return NULL;

    }

    return XICS_COMMON(dev);

}


static VncServerInfo *vnc_server_info_get(VncDisplay *vd)

{

    VncServerInfo *info;

    Error *err = NULL;

    info = g_malloc(sizeof(*info));

    vnc_init_basic_info_from_server_addr(vd->lsock,

                                         qapi_VncServerInfo_base(info), &err);

    info->has_auth = true;

    info->auth = g_strdup(vnc_auth_name(vd));

    if (err) {

        qapi_free_VncServerInfo(info);

        info = NULL;

        error_free(err);

    }

    return info;

}


static int vm_request_pending(void)

{

    return powerdown_requested ||

           reset_requested ||

           shutdown_requested ||

           debug_requested ||

           vmstop_requested;

}


static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,

                              const AVFrame *frame, int *got_packet_ptr)

{

    int n, i, ch, st, pkt_size, ret;

    const int16_t *samples;

    int16_t **samples_p;

    uint8_t *dst;

    ADPCMEncodeContext *c = avctx->priv_data;

    uint8_t *buf;

    samples = (const int16_t *)frame->data[0];

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

    st = avctx->channels == 2;

    if (avctx->codec_id == AV_CODEC_ID_ADPCM_SWF)

        pkt_size = (2 + avctx->channels * (22 + 4 * (frame->nb_samples - 1)) + 7) / 8;

    else

        pkt_size = avctx->block_align;

    if ((ret = ff_alloc_packet(avpkt, pkt_size))) {

        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");

        return ret;

    }

    dst = avpkt->data;

    switch(avctx->codec->id) {

    case AV_CODEC_ID_ADPCM_IMA_WAV:

    {

        int blocks, j;

        blocks = (frame->nb_samples - 1) / 8;

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

            ADPCMChannelStatus *status = &c->status[ch];

            status->prev_sample = samples_p[ch][0];

            /* status->step_index = 0;

               XXX: not sure how to init the state machine */

            bytestream_put_le16(&dst, status->prev_sample);

            *dst++ = status->step_index;

            *dst++ = 0; /* unknown */

        }

        /* stereo: 4 bytes (8 samples) for left, 4 bytes for right */

        if (avctx->trellis > 0) {

            FF_ALLOC_OR_GOTO(avctx, buf, avctx->channels * blocks * 8, error);

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

                adpcm_compress_trellis(avctx, &samples_p[ch][1],

                                       buf + ch * blocks * 8, &c->status[ch],

                                       blocks * 8, 1);

            }

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

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

                    uint8_t *buf1 = buf + ch * blocks * 8 + i * 8;

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

                        *dst++ = buf1[j] | (buf1[j + 1] << 4);

                }

            }

            av_free(buf);

        } else {

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

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

                    ADPCMChannelStatus *status = &c->status[ch];

                    const int16_t *smp = &samples_p[ch][1 + i * 8];

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

                        uint8_t v = adpcm_ima_compress_sample(status, smp[j    ]);

                        v        |= adpcm_ima_compress_sample(status, smp[j + 1]) << 4;

                        *dst++ = v;

                    }

                }

            }

        }

        break;

    }

    case AV_CODEC_ID_ADPCM_IMA_QT:

    {

        PutBitContext pb;

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

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

            ADPCMChannelStatus *status = &c->status[ch];

            put_bits(&pb, 9, (status->prev_sample & 0xFFFF) >> 7);

            put_bits(&pb, 7,  status->step_index);

            if (avctx->trellis > 0) {

                uint8_t buf[64];

                adpcm_compress_trellis(avctx, &samples_p[ch][1], buf, status,

                                       64, 1);

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

                    put_bits(&pb, 4, buf[i ^ 1]);

            } else {

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

                    int t1, t2;

                    t1 = adpcm_ima_qt_compress_sample(status, samples_p[ch][i    ]);

                    t2 = adpcm_ima_qt_compress_sample(status, samples_p[ch][i + 1]);

                    put_bits(&pb, 4, t2);

                    put_bits(&pb, 4, t1);

                }

            }

        }

        flush_put_bits(&pb);

        break;

    }

    case AV_CODEC_ID_ADPCM_SWF:

    {

        PutBitContext pb;

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

        n = frame->nb_samples - 1;

        // store AdpcmCodeSize

        put_bits(&pb, 2, 2);    // set 4-bit flash adpcm format

        // init the encoder state

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

            // clip step so it fits 6 bits

            c->status[i].step_index = av_clip(c->status[i].step_index, 0, 63);

            put_sbits(&pb, 16, samples[i]);

            put_bits(&pb, 6, c->status[i].step_index);

            c->status[i].prev_sample = samples[i];

        }

        if (avctx->trellis > 0) {

            FF_ALLOC_OR_GOTO(avctx, buf, 2 * n, error);

            adpcm_compress_trellis(avctx, samples + avctx->channels, buf,

                                   &c->status[0], n, avctx->channels);

            if (avctx->channels == 2)

                adpcm_compress_trellis(avctx, samples + avctx->channels + 1,

                                       buf + n, &c->status[1], n,

                                       avctx->channels);

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

                put_bits(&pb, 4, buf[i]);

                if (avctx->channels == 2)

                    put_bits(&pb, 4, buf[n + i]);

            }

            av_free(buf);

        } else {

            for (i = 1; i < frame->nb_samples; i++) {

                put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[0],

                         samples[avctx->channels * i]));

                if (avctx->channels == 2)

                    put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[1],

                             samples[2 * i + 1]));

            }

        }

        flush_put_bits(&pb);

        break;

    }

    case AV_CODEC_ID_ADPCM_MS:

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

            int predictor = 0;

            *dst++ = predictor;

            c->status[i].coeff1 = ff_adpcm_AdaptCoeff1[predictor];

            c->status[i].coeff2 = ff_adpcm_AdaptCoeff2[predictor];

        }

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

            if (c->status[i].idelta < 16)

                c->status[i].idelta = 16;

            bytestream_put_le16(&dst, c->status[i].idelta);

        }

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

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

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

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

            bytestream_put_le16(&dst, c->status[i].sample1);

        }

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

            bytestream_put_le16(&dst, c->status[i].sample2);

        if (avctx->trellis > 0) {

            n = avctx->block_align - 7 * avctx->channels;

            FF_ALLOC_OR_GOTO(avctx, buf, 2 * n, error);

            if (avctx->channels == 1) {

                adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n,

                                       avctx->channels);

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

                    *dst++ = (buf[i] << 4) | buf[i + 1];

            } else {

                adpcm_compress_trellis(avctx, samples,     buf,

                                       &c->status[0], n, avctx->channels);

                adpcm_compress_trellis(avctx, samples + 1, buf + n,

                                       &c->status[1], n, avctx->channels);

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

                    *dst++ = (buf[i] << 4) | buf[n + i];

            }

            av_free(buf);

        } else {

            for (i = 7 * avctx->channels; i < avctx->block_align; i++) {

                int nibble;

                nibble  = adpcm_ms_compress_sample(&c->status[ 0], *samples++) << 4;

                nibble |= adpcm_ms_compress_sample(&c->status[st], *samples++);

                *dst++  = nibble;

            }

        }

        break;

    case AV_CODEC_ID_ADPCM_YAMAHA:

        n = frame->nb_samples / 2;

        if (avctx->trellis > 0) {

            FF_ALLOC_OR_GOTO(avctx, buf, 2 * n * 2, error);

            n *= 2;

            if (avctx->channels == 1) {

                adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n,

                                       avctx->channels);

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

                    *dst++ = buf[i] | (buf[i + 1] << 4);

            } else {

                adpcm_compress_trellis(avctx, samples,     buf,

                                       &c->status[0], n, avctx->channels);

                adpcm_compress_trellis(avctx, samples + 1, buf + n,

                                       &c->status[1], n, avctx->channels);

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

                    *dst++ = buf[i] | (buf[n + i] << 4);

            }

            av_free(buf);

        } else

            for (n *= avctx->channels; n > 0; n--) {

                int nibble;

                nibble  = adpcm_yamaha_compress_sample(&c->status[ 0], *samples++);

                nibble |= adpcm_yamaha_compress_sample(&c->status[st], *samples++) << 4;

                *dst++  = nibble;

            }

        break;

    default:

        return AVERROR(EINVAL);

    }

    avpkt->size = pkt_size;

    *got_packet_ptr = 1;

    return 0;

error:

    return AVERROR(ENOMEM);

}


yuv2rgb_full_2_c_template(SwsContext *c, const int16_t *buf[2],

                     const int16_t *ubuf[2], const int16_t *vbuf[2],

                     const int16_t *abuf[2], uint8_t *dest, int dstW,

                     int yalpha, int uvalpha, int y,

                     enum AVPixelFormat target, int hasAlpha)

{

    const int16_t *buf0  = buf[0],  *buf1  = buf[1],

                  *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],

                  *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],

                  *abuf0 = hasAlpha ? abuf[0] : NULL,

                  *abuf1 = hasAlpha ? abuf[1] : NULL;

    int  yalpha1 = 4096 - yalpha;

    int uvalpha1 = 4096 - uvalpha;

    int i;

    int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;

    int err[4] = {0};

    if(   target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE

       || target == AV_PIX_FMT_BGR8      || target == AV_PIX_FMT_RGB8)

        step = 1;

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

        int Y = ( buf0[i] * yalpha1  +  buf1[i] * yalpha             ) >> 10; //FIXME rounding

        int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha-(128 << 19)) >> 10;

        int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha-(128 << 19)) >> 10;

        int A;

        if (hasAlpha) {

            A = (abuf0[i] * yalpha1 + abuf1[i] * yalpha + (1<<18)) >> 19;

            if (A & 0x100)

                A = av_clip_uint8(A);

        }

        yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err);

        dest += step;

    }

    c->dither_error[0][i] = err[0];

    c->dither_error[1][i] = err[1];

    c->dither_error[2][i] = err[2];

}


static void clone_slice(H264Context *dst, H264Context *src)

{

    memcpy(dst->block_offset, src->block_offset, sizeof(dst->block_offset));

    dst->s.current_picture_ptr = src->s.current_picture_ptr;

    dst->s.current_picture     = src->s.current_picture;

    dst->s.linesize            = src->s.linesize;

    dst->s.uvlinesize          = src->s.uvlinesize;

    dst->s.first_field         = src->s.first_field;

    dst->prev_poc_msb          = src->prev_poc_msb;

    dst->prev_poc_lsb          = src->prev_poc_lsb;

    dst->prev_frame_num_offset = src->prev_frame_num_offset;

    dst->prev_frame_num        = src->prev_frame_num;

    dst->short_ref_count       = src->short_ref_count;

    memcpy(dst->short_ref,        src->short_ref,        sizeof(dst->short_ref));

    memcpy(dst->long_ref,         src->long_ref,         sizeof(dst->long_ref));

    memcpy(dst->default_ref_list, src->default_ref_list, sizeof(dst->default_ref_list));

    memcpy(dst->ref_list,         src->ref_list,         sizeof(dst->ref_list));

    memcpy(dst->dequant4_coeff,   src->dequant4_coeff,   sizeof(src->dequant4_coeff));

    memcpy(dst->dequant8_coeff,   src->dequant8_coeff,   sizeof(src->dequant8_coeff));

}


static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,

                                     TCGv arg2, int add_ca, int compute_ca,

                                     int compute_ov)

{

    TCGv t0, t1;

    if ((!compute_ca && !compute_ov) ||

        (!TCGV_EQUAL(ret, arg1) && !TCGV_EQUAL(ret, arg2)))  {

        t0 = ret;

    } else {

        t0 = tcg_temp_local_new();

    }

    if (add_ca) {

        t1 = tcg_temp_local_new();

        tcg_gen_mov_tl(t1, cpu_ca);

    } else {

        TCGV_UNUSED(t1);

    }

    if (compute_ca) {

        /* Start with XER CA disabled, the most likely case */

        tcg_gen_movi_tl(cpu_ca, 0);

    }

    if (compute_ov) {

        /* Start with XER OV disabled, the most likely case */

        tcg_gen_movi_tl(cpu_ov, 0);

    }

    if (add_ca) {

        tcg_gen_not_tl(t0, arg1);

        tcg_gen_add_tl(t0, t0, arg2);

        gen_op_arith_compute_ca(ctx, t0, arg2, 0);

        tcg_gen_add_tl(t0, t0, t1);

        gen_op_arith_compute_ca(ctx, t0, t1, 0);

        tcg_temp_free(t1);

    } else {

        tcg_gen_sub_tl(t0, arg2, arg1);

        if (compute_ca) {

            gen_op_arith_compute_ca(ctx, t0, arg2, 1);

        }

    }

    if (compute_ov) {

        gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);

    }

    if (unlikely(Rc(ctx->opcode) != 0))

        gen_set_Rc0(ctx, t0);

    if (!TCGV_EQUAL(t0, ret)) {

        tcg_gen_mov_tl(ret, t0);

        tcg_temp_free(t0);

    }

}


static void mxf_packet_timestamps(MXFContext *mxf, AVPacket *pkt)

{

    int64_t last_ofs = -1, next_ofs;

    MXFIndexTable *t = &mxf->index_tables[0];

    /* this is called from the OP1a demuxing logic, which means there

     * may be no index tables */

    if (mxf->nb_index_tables <= 0)

        return;

    /* find mxf->current_edit_unit so that the next edit unit starts ahead of pkt->pos */

    for (;;) {

        if (mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit + 1, NULL, &next_ofs, 0) < 0)

            break;

        if (next_ofs <= last_ofs) {

            /* large next_ofs didn't change or current_edit_unit wrapped

             * around this fixes the infinite loop on zzuf3.mxf */

            av_log(mxf->fc, AV_LOG_ERROR,

                   "next_ofs didn't change. not deriving packet timestamps\n");

            return;

        }

        if (next_ofs > pkt->pos)

            break;

        last_ofs = next_ofs;

        mxf->current_edit_unit++;

    }

    if (mxf->current_edit_unit >= t->nb_ptses)

        return;

    pkt->dts = mxf->current_edit_unit + t->first_dts;

    pkt->pts = t->ptses[mxf->current_edit_unit];

}


static void ff_h264_idct_add16intra_mmx(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){

    int i;

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

        if(nnzc[ scan8[i] ] || block[i*16])

            ff_h264_idct_add_mmx(dst + block_offset[i], block + i*16, stride);

    }

}


static void process_subpacket_9 (QDM2Context *q, QDM2SubPNode *node)

{

    GetBitContext gb;

    int i, j, k, n, ch, run, level, diff;

    init_get_bits(&gb, node->packet->data, node->packet->size*8);

    n = coeff_per_sb_for_avg[q->coeff_per_sb_select][QDM2_SB_USED(q->sub_sampling) - 1] + 1; // same as averagesomething function

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

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

            level = qdm2_get_vlc(&gb, &vlc_tab_level, 0, 2);

            q->quantized_coeffs[ch][i][0] = level;

            for (j = 0; j < (8 - 1); ) {

                run = qdm2_get_vlc(&gb, &vlc_tab_run, 0, 1) + 1;

                diff = qdm2_get_se_vlc(&vlc_tab_diff, &gb, 2);

                for (k = 1; k <= run; k++)

                    q->quantized_coeffs[ch][i][j + k] = (level + ((k*diff) / run));

                level += diff;

                j += run;

            }

        }

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

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

            q->quantized_coeffs[ch][0][i] = 0;

}


static inline void h264_loop_filter_chroma_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0)

{

    int i, d;

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

        const int tc = tc0[i];

        if( tc <= 0 ) {

            pix += 2*ystride;

            continue;

        }

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

            const int p0 = pix[-1*xstride];

            const int p1 = pix[-2*xstride];

            const int q0 = pix[0];

            const int q1 = pix[1*xstride];

            if( FFABS( p0 - q0 ) < alpha &&

                FFABS( p1 - p0 ) < beta &&

                FFABS( q1 - q0 ) < beta ) {

                int delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );

                pix[-xstride] = av_clip_uint8( p0 + delta );    /* p0' */

                pix[0]        = av_clip_uint8( q0 - delta );    /* q0' */

            }

            pix += ystride;

        }

    }

}


static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst,
                                    const uint8_t *src, const uint8_t *src_end,
                                    int width, int esc_count)
{
    int i = 0;
    int count;
    uint8_t zero_run = 0;
    const uint8_t *src_start = src;
    uint8_t mask1 = -(esc_count < 2);
    uint8_t mask2 = -(esc_count < 3);
    uint8_t *end = dst + (width - 2);
output_zeros:
    if (l->zeros_rem) {
        count = FFMIN(l->zeros_rem, width - i);
        if (end - dst < count) {
            av_log(l->avctx, AV_LOG_ERROR, "Too many zeros remaining.\n");
            return AVERROR_INVALIDDATA;
        }
        memset(dst, 0, count);
        l->zeros_rem -= count;
        dst += count;
    }
    while (dst < end) {
        i = 0;
        while (!zero_run && dst + i < end) {
            i++;
            if (i+2 >= src_end - src)
                return AVERROR_INVALIDDATA;
            zero_run =
                !(src[i] | (src[i + 1] & mask1) | (src[i + 2] & mask2));
        }
        if (zero_run) {
            zero_run = 0;
            i += esc_count;
            memcpy(dst, src, i);
            dst += i;
            l->zeros_rem = lag_calc_zero_run(src[i]);
            src += i + 1;
            goto output_zeros;
        } else {
            memcpy(dst, src, i);
            src += i;
            dst += i;
        }
    }
    return  src - src_start;
}


static int ffmmal_read_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame)

{

    MMALDecodeContext *ctx = avctx->priv_data;

    MMAL_BUFFER_HEADER_T *buffer = NULL;

    MMAL_STATUS_T status = 0;

    int ret = 0;

    if (ctx->eos_received)

        goto done;

    while (1) {

        // To ensure decoding in lockstep with a constant delay between fed packets

        // and output frames, we always wait until an output buffer is available.

        // Except during start we don't know after how many input packets the decoder

        // is going to return the first buffer, and we can't distinguish decoder

        // being busy from decoder waiting for input. So just poll at the start and

        // keep feeding new data to the buffer.

        // We are pretty sure the decoder will produce output if we sent more input

        // frames than what a h264 decoder could logically delay. This avoids too

        // excessive buffering.

        // We also wait if we sent eos, but didn't receive it yet (think of decoding

        // stream with a very low number of frames).

        if (ctx->frames_output || ctx->packets_sent > MAX_DELAYED_FRAMES ||

            (ctx->packets_sent && ctx->eos_sent)) {

            // MMAL will ignore broken input packets, which means the frame we

            // expect here may never arrive. Dealing with this correctly is

            // complicated, so here's a hack to avoid that it freezes forever

            // in this unlikely situation.

            buffer = mmal_queue_timedwait(ctx->queue_decoded_frames, 100);

            if (!buffer) {

                av_log(avctx, AV_LOG_ERROR, "Did not get output frame from MMAL.\n");

                ret = AVERROR_UNKNOWN;

                goto done;

            }

        } else {

            buffer = mmal_queue_get(ctx->queue_decoded_frames);

            if (!buffer)

                goto done;

        }

        ctx->eos_received |= !!(buffer->flags & MMAL_BUFFER_HEADER_FLAG_EOS);

        if (ctx->eos_received)

            goto done;

        if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) {

            MMAL_COMPONENT_T *decoder = ctx->decoder;

            MMAL_EVENT_FORMAT_CHANGED_T *ev = mmal_event_format_changed_get(buffer);

            MMAL_BUFFER_HEADER_T *stale_buffer;

            av_log(avctx, AV_LOG_INFO, "Changing output format.\n");

            if ((status = mmal_port_disable(decoder->output[0])))

                goto done;

            while ((stale_buffer = mmal_queue_get(ctx->queue_decoded_frames)))

                mmal_buffer_header_release(stale_buffer);

            mmal_format_copy(decoder->output[0]->format, ev->format);

            if ((ret = ffmal_update_format(avctx)) < 0)

                goto done;

            if ((status = mmal_port_enable(decoder->output[0], output_callback)))

                goto done;

            if ((ret = ffmmal_fill_output_port(avctx)) < 0)

                goto done;

            if ((ret = ffmmal_fill_input_port(avctx)) < 0)

                goto done;

            mmal_buffer_header_release(buffer);

            continue;

        } else if (buffer->cmd) {

            char s[20];

            av_get_codec_tag_string(s, sizeof(s), buffer->cmd);

            av_log(avctx, AV_LOG_WARNING, "Unknown MMAL event %s on output port\n", s);

            goto done;

        } else if (buffer->length == 0) {

            // Unused output buffer that got drained after format change.

            mmal_buffer_header_release(buffer);

            continue;

        }

        ctx->frames_output++;

        if ((ret = ffmal_copy_frame(avctx, frame, buffer)) < 0)

            goto done;

        *got_frame = 1;

        break;

    }

done:

    if (buffer)

        mmal_buffer_header_release(buffer);

    if (status && ret >= 0)

        ret = AVERROR_UNKNOWN;

    return ret;

}