static int xiph_parse_sdp_line(AVFormatContext *s, int st_index,

                                 PayloadContext *data, const char *line)

{

    const char *p;

    char *value;

    char attr[25];

    int value_size = strlen(line), attr_size = sizeof(attr), res = 0;

    AVCodecContext* codec = s->streams[st_index]->codec;

    assert(codec->id == CODEC_ID_THEORA);

    assert(data);

    if (!(value = av_malloc(value_size))) {

        av_log(codec, AV_LOG_ERROR, "Out of memory\n");

        return AVERROR(ENOMEM);

    }

    if (av_strstart(line, "fmtp:", &p)) {

        // remove protocol identifier

        while (*p && *p == ' ') p++; // strip spaces

        while (*p && *p != ' ') p++; // eat protocol identifier

        while (*p && *p == ' ') p++; // strip trailing spaces

        while (ff_rtsp_next_attr_and_value(&p,

                                           attr, attr_size,

                                           value, value_size)) {

            res = xiph_parse_fmtp_pair(codec, data, attr, value);

            if (res < 0 && res != AVERROR_PATCHWELCOME)

                return res;

        }

    }

    av_free(value);

    return 0;

}


static int vp8_handle_packet(AVFormatContext *ctx, PayloadContext *vp8,

                             AVStream *st, AVPacket *pkt, uint32_t *timestamp,

                             const uint8_t *buf, int len, uint16_t seq,

                             int flags)

{

    int start_partition, end_packet;

    int extended_bits, part_id;

    int pictureid_present = 0, tl0picidx_present = 0, tid_present = 0,

        keyidx_present = 0;

    int pictureid = -1, pictureid_mask = 0;

    int returned_old_frame = 0;

    uint32_t old_timestamp;

    if (!buf) {

        if (vp8->data) {

            int ret = ff_rtp_finalize_packet(pkt, &vp8->data, st->index);

            if (ret < 0)

                return ret;

            *timestamp = vp8->timestamp;

            if (vp8->sequence_dirty)

                pkt->flags |= AV_PKT_FLAG_CORRUPT;

            return 0;

        }

        return AVERROR(EAGAIN);

    }

    if (len < 1)

        return AVERROR_INVALIDDATA;

    extended_bits   = buf[0] & 0x80;

    start_partition = buf[0] & 0x10;

    part_id         = buf[0] & 0x0f;

    end_packet      = flags & RTP_FLAG_MARKER;

    buf++;

    len--;

    if (extended_bits) {

        if (len < 1)

            return AVERROR_INVALIDDATA;

        pictureid_present = buf[0] & 0x80;

        tl0picidx_present = buf[0] & 0x40;

        tid_present       = buf[0] & 0x20;

        keyidx_present    = buf[0] & 0x10;

        buf++;

        len--;

    }

    if (pictureid_present) {

        if (len < 1)

            return AVERROR_INVALIDDATA;

        if (buf[0] & 0x80) {

            if (len < 2)

                return AVERROR_INVALIDDATA;

            pictureid = AV_RB16(buf) & 0x7fff;

            pictureid_mask = 0x7fff;

            buf += 2;

            len -= 2;

        } else {

            pictureid = buf[0] & 0x7f;

            pictureid_mask = 0x7f;

            buf++;

            len--;

        }

    }

    if (tl0picidx_present) {

        // Ignoring temporal level zero index

        buf++;

        len--;

    }

    if (tid_present || keyidx_present) {

        // Ignoring temporal layer index, layer sync bit and keyframe index

        buf++;

        len--;

    }

    if (len < 1)

        return AVERROR_INVALIDDATA;

    if (start_partition && part_id == 0 && len >= 3) {

        int res;

        int non_key = buf[0] & 0x01;

        if (!non_key) {

            vp8_free_buffer(vp8);

            // Keyframe, decoding ok again

            vp8->sequence_ok = 1;

            vp8->sequence_dirty = 0;

            vp8->got_keyframe = 1;

        } else {

            int can_continue = vp8->data && !vp8->is_keyframe &&

                               avio_tell(vp8->data) >= vp8->first_part_size;

            if (!vp8->sequence_ok)

                return AVERROR(EAGAIN);

            if (!vp8->got_keyframe)

                return vp8_broken_sequence(ctx, vp8, "Keyframe missing\n");

            if (pictureid >= 0) {

                if (pictureid != ((vp8->prev_pictureid + 1) & pictureid_mask)) {

                    return vp8_broken_sequence(ctx, vp8,

                                               "Missed a picture, sequence broken\n");

                } else {

                    if (vp8->data && !can_continue)

                        return vp8_broken_sequence(ctx, vp8,

                                                   "Missed a picture, sequence broken\n");

                }

            } else {

                uint16_t expected_seq = vp8->prev_seq + 1;

                int16_t diff = seq - expected_seq;

                if (vp8->data) {

                    // No picture id, so we can't know if missed packets

                    // contained any new frames. If diff == 0, we did get

                    // later packets from the same frame (matching timestamp),

                    // so we know we didn't miss any frame. If diff == 1 and

                    // we still have data (not flushed by the end of frame

                    // marker), the single missed packet must have been part

                    // of the same frame.

                    if ((diff == 0 || diff == 1) && can_continue) {

                        // Proceed with what we have

                    } else {

                        return vp8_broken_sequence(ctx, vp8,

                                                   "Missed too much, sequence broken\n");

                    }

                } else {

                    if (diff != 0)

                        return vp8_broken_sequence(ctx, vp8,

                                                   "Missed unknown data, sequence broken\n");

                }

            }

            if (vp8->data) {

                vp8->sequence_dirty = 1;

                if (avio_tell(vp8->data) >= vp8->first_part_size) {

                    int ret = ff_rtp_finalize_packet(pkt, &vp8->data, st->index);

                    if (ret < 0)

                        return ret;

                    pkt->flags |= AV_PKT_FLAG_CORRUPT;

                    returned_old_frame = 1;

                    old_timestamp = vp8->timestamp;

                } else {

                    // Shouldn't happen

                    vp8_free_buffer(vp8);

                }

            }

        }

        vp8->first_part_size = (AV_RL16(&buf[1]) << 3 | buf[0] >> 5) + 3;

        if ((res = avio_open_dyn_buf(&vp8->data)) < 0)

            return res;

        vp8->timestamp = *timestamp;

        vp8->broken_frame = 0;

        vp8->prev_pictureid = pictureid;

        vp8->is_keyframe = !non_key;

    } else {

        uint16_t expected_seq = vp8->prev_seq + 1;

        if (!vp8->sequence_ok)

            return AVERROR(EAGAIN);

        if (vp8->timestamp != *timestamp) {

            // Missed the start of the new frame, sequence broken

            return vp8_broken_sequence(ctx, vp8,

                                       "Received no start marker; dropping frame\n");

        }

        if (seq != expected_seq) {

            if (vp8->is_keyframe) {

                return vp8_broken_sequence(ctx, vp8,

                                           "Missed part of a keyframe, sequence broken\n");

            } else if (vp8->data && avio_tell(vp8->data) >= vp8->first_part_size) {

                vp8->broken_frame = 1;

                vp8->sequence_dirty = 1;

            } else {

                return vp8_broken_sequence(ctx, vp8,

                                           "Missed part of the first partition, sequence broken\n");

            }

        }

    }

    if (!vp8->data)

        return vp8_broken_sequence(ctx, vp8, "Received no start marker\n");

    vp8->prev_seq = seq;

    if (!vp8->broken_frame)

        avio_write(vp8->data, buf, len);

    if (returned_old_frame) {

        *timestamp = old_timestamp;

        return end_packet ? 1 : 0;

    }

    if (end_packet) {

        int ret;

        ret = ff_rtp_finalize_packet(pkt, &vp8->data, st->index);

        if (ret < 0)

            return ret;

        if (vp8->sequence_dirty)

            pkt->flags |= AV_PKT_FLAG_CORRUPT;

        return 0;

    }

    return AVERROR(EAGAIN);

}


static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){

    MpegEncContext * const s = avctx->priv_data;

    MJpegContext * const m = s->mjpeg_ctx;

    AVFrame *pict = data;

    const int width= s->width;

    const int height= s->height;

    AVFrame * const p= (AVFrame*)&s->current_picture;

    const int predictor= avctx->prediction_method+1;

    init_put_bits(&s->pb, buf, buf_size);

    *p = *pict;

    p->pict_type= FF_I_TYPE;

    p->key_frame= 1;

    mjpeg_picture_header(s);

    s->header_bits= put_bits_count(&s->pb);

    if(avctx->pix_fmt == PIX_FMT_RGBA32){

        int x, y, i;

        const int linesize= p->linesize[0];

        uint16_t buffer[2048][4];

        int left[3], top[3], topleft[3];

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

            buffer[0][i]= 1 << (9 - 1);

        }

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

            const int modified_predictor= y ? predictor : 1;

            uint8_t *ptr = p->data[0] + (linesize * y);

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

                top[i]= left[i]= topleft[i]= buffer[0][i];

            }

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

                buffer[x][1] = ptr[4*x+0] - ptr[4*x+1] + 0x100;

                buffer[x][2] = ptr[4*x+2] - ptr[4*x+1] + 0x100;

                buffer[x][0] = (ptr[4*x+0] + 2*ptr[4*x+1] + ptr[4*x+2])>>2;

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

                    int pred, diff;

                    PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);

                    topleft[i]= top[i];

                    top[i]= buffer[x+1][i];

                    left[i]= buffer[x][i];

                    diff= ((left[i] - pred + 0x100)&0x1FF) - 0x100;

                    if(i==0)

                        mjpeg_encode_dc(s, diff, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly

                    else

                        mjpeg_encode_dc(s, diff, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);

                }

            }

        }

    }else{

        int mb_x, mb_y, i;

        const int mb_width  = (width  + s->mjpeg_hsample[0] - 1) / s->mjpeg_hsample[0];

        const int mb_height = (height + s->mjpeg_vsample[0] - 1) / s->mjpeg_vsample[0];

        for(mb_y = 0; mb_y < mb_height; mb_y++) {

            for(mb_x = 0; mb_x < mb_width; mb_x++) {

                if(mb_x==0 || mb_y==0){

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

                        uint8_t *ptr;

                        int x, y, h, v, linesize;

                        h = s->mjpeg_hsample[i];

                        v = s->mjpeg_vsample[i];

                        linesize= p->linesize[i];

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

                            for(x=0; x<h; x++){

                                int pred;

                                ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap

                                if(y==0 && mb_y==0){

                                    if(x==0 && mb_x==0){

                                        pred= 128;

                                    }else{

                                        pred= ptr[-1];

                                    }

                                }else{

                                    if(x==0 && mb_x==0){

                                        pred= ptr[-linesize];

                                    }else{

                                        PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);

                                    }

                                }

                                if(i==0)

                                    mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly

                                else

                                    mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);

                            }

                        }

                    }

                }else{

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

                        uint8_t *ptr;

                        int x, y, h, v, linesize;

                        h = s->mjpeg_hsample[i];

                        v = s->mjpeg_vsample[i];

                        linesize= p->linesize[i];

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

                            for(x=0; x<h; x++){

                                int pred;

                                ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap

//printf("%d %d %d %d %8X\n", mb_x, mb_y, x, y, ptr);

                                PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);

                                if(i==0)

                                    mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly

                                else

                                    mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);

                            }

                        }

                    }

                }

            }

        }

    }

    emms_c();

    mjpeg_picture_trailer(s);

    s->picture_number++;

    flush_put_bits(&s->pb);

    return pbBufPtr(&s->pb) - s->pb.buf;

//    return (put_bits_count(&f->pb)+7)/8;

}


static VFIOGroup *vfio_get_group(int groupid)

{

    VFIOGroup *group;

    char path[32];

    struct vfio_group_status status = { .argsz = sizeof(status) };

    QLIST_FOREACH(group, &group_list, next) {

        if (group->groupid == groupid) {

            return group;

        }

    }

    group = g_malloc0(sizeof(*group));

    snprintf(path, sizeof(path), "/dev/vfio/%d", groupid);

    group->fd = qemu_open(path, O_RDWR);

    if (group->fd < 0) {

        error_report("vfio: error opening %s: %m", path);

        goto free_group_exit;

    }

    if (ioctl(group->fd, VFIO_GROUP_GET_STATUS, &status)) {

        error_report("vfio: error getting group status: %m");

        goto close_fd_exit;

    }

    if (!(status.flags & VFIO_GROUP_FLAGS_VIABLE)) {

        error_report("vfio: error, group %d is not viable, please ensure "

                     "all devices within the iommu_group are bound to their "

                     "vfio bus driver.", groupid);

        goto close_fd_exit;

    }

    group->groupid = groupid;

    QLIST_INIT(&group->device_list);

    if (vfio_connect_container(group)) {

        error_report("vfio: failed to setup container for group %d", groupid);

        goto close_fd_exit;

    }

    if (QLIST_EMPTY(&group_list)) {

        qemu_register_reset(vfio_pci_reset_handler, NULL);

    }

    QLIST_INSERT_HEAD(&group_list, group, next);

    vfio_kvm_device_add_group(group);

    return group;

close_fd_exit:

    close(group->fd);

free_group_exit:

    g_free(group);

    return NULL;

}


static int webvtt_event_to_ass(AVBPrint *buf, const char *p)

{

    int i, again, skip = 0;

    while (*p) {

        for (i = 0; i < FF_ARRAY_ELEMS(webvtt_tag_replace); i++) {

            const char *from = webvtt_tag_replace[i].from;

            const size_t len = strlen(from);

            if (!strncmp(p, from, len)) {

                av_bprintf(buf, "%s", webvtt_tag_replace[i].to);

                p += len;

                again = 1;

                break;

            }

        }

        if (!*p)

            break;

        if (again) {

            again = 0;

            skip = 0;

            continue;

        }

        if (*p == '<')

            skip = 1;

        else if (*p == '>')

            skip = 0;

        else if (p[0] == '\n' && p[1])

            av_bprintf(buf, "\\N");

        else if (!skip && *p != '\r')

            av_bprint_chars(buf, *p, 1);

        p++;

    }

    return 0;

}


static int nuv_probe(AVProbeData *p) {

    if (p->buf_size < 12)

        return 0;

    if (!memcmp(p->buf, "NuppelVideo", 12))

        return AVPROBE_SCORE_MAX;

    if (!memcmp(p->buf, "MythTVVideo", 12))

        return AVPROBE_SCORE_MAX;

    return 0;

}


void cache_fini(PageCache *cache)

{

    int64_t i;

    g_assert(cache);

    g_assert(cache->page_cache);

    for (i = 0; i < cache->max_num_items; i++) {

        g_free(cache->page_cache[i].it_data);

    }

    g_free(cache->page_cache);

    cache->page_cache = NULL;

}


int ff_rate_control_init(MpegEncContext *s)

{

    RateControlContext *rcc= &s->rc_context;

    int i;

    const char *error = NULL;

    static const char * const const_names[]={

        "PI",

        "E",

        "iTex",

        "pTex",

        "tex",

        "mv",

        "fCode",

        "iCount",

        "mcVar",

        "var",

        "isI",

        "isP",

        "isB",

        "avgQP",

        "qComp",

/*        "lastIQP",

        "lastPQP",

        "lastBQP",

        "nextNonBQP",*/

        "avgIITex",

        "avgPITex",

        "avgPPTex",

        "avgBPTex",

        "avgTex",

        NULL

    };

    static double (*func1[])(void *, double)={

        (void *)bits2qp,

        (void *)qp2bits,

        NULL

    };

    static const char * const func1_names[]={

        "bits2qp",

        "qp2bits",

        NULL

    };

    emms_c();

    rcc->rc_eq_eval = ff_parse(s->avctx->rc_eq, const_names, func1, func1_names, NULL, NULL, &error);

    if (!rcc->rc_eq_eval) {

        av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\": %s\n", s->avctx->rc_eq, error? error : "");

        return -1;

    }

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

        rcc->pred[i].coeff= FF_QP2LAMBDA * 7.0;

        rcc->pred[i].count= 1.0;

        rcc->pred[i].decay= 0.4;

        rcc->i_cplx_sum [i]=

        rcc->p_cplx_sum [i]=

        rcc->mv_bits_sum[i]=

        rcc->qscale_sum [i]=

        rcc->frame_count[i]= 1; // 1 is better because of 1/0 and such

        rcc->last_qscale_for[i]=FF_QP2LAMBDA * 5;

    }

    rcc->buffer_index= s->avctx->rc_initial_buffer_occupancy;

    if(s->flags&CODEC_FLAG_PASS2){

        int i;

        char *p;

        /* find number of pics */

        p= s->avctx->stats_in;

        for(i=-1; p; i++){

            p= strchr(p+1, ';');

        }

        i+= s->max_b_frames;

        if(i<=0 || i>=INT_MAX / sizeof(RateControlEntry))

            return -1;

        rcc->entry = av_mallocz(i*sizeof(RateControlEntry));

        rcc->num_entries= i;

        /* init all to skipped p frames (with b frames we might have a not encoded frame at the end FIXME) */

        for(i=0; i<rcc->num_entries; i++){

            RateControlEntry *rce= &rcc->entry[i];

            rce->pict_type= rce->new_pict_type=FF_P_TYPE;

            rce->qscale= rce->new_qscale=FF_QP2LAMBDA * 2;

            rce->misc_bits= s->mb_num + 10;

            rce->mb_var_sum= s->mb_num*100;

        }

        /* read stats */

        p= s->avctx->stats_in;

        for(i=0; i<rcc->num_entries - s->max_b_frames; i++){

            RateControlEntry *rce;

            int picture_number;

            int e;

            char *next;

            next= strchr(p, ';');

            if(next){

                (*next)=0; //sscanf in unbelievably slow on looong strings //FIXME copy / do not write

                next++;

            }

            e= sscanf(p, " in:%d ", &picture_number);

            assert(picture_number >= 0);

            assert(picture_number < rcc->num_entries);

            rce= &rcc->entry[picture_number];

            e+=sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d",

                   &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits, &rce->mv_bits, &rce->misc_bits,

                   &rce->f_code, &rce->b_code, &rce->mc_mb_var_sum, &rce->mb_var_sum, &rce->i_count, &rce->skip_count, &rce->header_bits);

            if(e!=14){

                av_log(s->avctx, AV_LOG_ERROR, "statistics are damaged at line %d, parser out=%d\n", i, e);

                return -1;

            }

            p= next;

        }

        if(init_pass2(s) < 0) return -1;

        //FIXME maybe move to end

        if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) {

#ifdef CONFIG_LIBXVID

            return ff_xvid_rate_control_init(s);

#else

            av_log(s->avctx, AV_LOG_ERROR, "Xvid ratecontrol requires libavcodec compiled with Xvid support.\n");

            return -1;

#endif

        }

    }

    if(!(s->flags&CODEC_FLAG_PASS2)){

        rcc->short_term_qsum=0.001;

        rcc->short_term_qcount=0.001;

        rcc->pass1_rc_eq_output_sum= 0.001;

        rcc->pass1_wanted_bits=0.001;

        if(s->avctx->qblur > 1.0){

            av_log(s->avctx, AV_LOG_ERROR, "qblur too large\n");

            return -1;

        }

        /* init stuff with the user specified complexity */

        if(s->avctx->rc_initial_cplx){

            for(i=0; i<60*30; i++){

                double bits= s->avctx->rc_initial_cplx * (i/10000.0 + 1.0)*s->mb_num;

                RateControlEntry rce;

                double q;

                if     (i%((s->gop_size+3)/4)==0) rce.pict_type= FF_I_TYPE;

                else if(i%(s->max_b_frames+1))    rce.pict_type= FF_B_TYPE;

                else                              rce.pict_type= FF_P_TYPE;

                rce.new_pict_type= rce.pict_type;

                rce.mc_mb_var_sum= bits*s->mb_num/100000;

                rce.mb_var_sum   = s->mb_num;

                rce.qscale   = FF_QP2LAMBDA * 2;

                rce.f_code   = 2;

                rce.b_code   = 1;

                rce.misc_bits= 1;

                if(s->pict_type== FF_I_TYPE){

                    rce.i_count   = s->mb_num;

                    rce.i_tex_bits= bits;

                    rce.p_tex_bits= 0;

                    rce.mv_bits= 0;

                }else{

                    rce.i_count   = 0; //FIXME we do know this approx

                    rce.i_tex_bits= 0;

                    rce.p_tex_bits= bits*0.9;

                    rce.mv_bits= bits*0.1;

                }

                rcc->i_cplx_sum [rce.pict_type] += rce.i_tex_bits*rce.qscale;

                rcc->p_cplx_sum [rce.pict_type] += rce.p_tex_bits*rce.qscale;

                rcc->mv_bits_sum[rce.pict_type] += rce.mv_bits;

                rcc->frame_count[rce.pict_type] ++;

                bits= rce.i_tex_bits + rce.p_tex_bits;

                q= get_qscale(s, &rce, rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum, i);

                rcc->pass1_wanted_bits+= s->bit_rate/(1/av_q2d(s->avctx->time_base)); //FIXME misbehaves a little for variable fps

            }

        }

    }

    return 0;

}


static int iec61883_read_header(AVFormatContext *context)

{

    struct iec61883_data *dv = context->priv_data;

    struct raw1394_portinfo pinf[16];

    rom1394_directory rom_dir;

    char *endptr;

    int inport;

    int nb_ports;

    int port = -1;

    int response;

    int i, j = 0;

    uint64_t guid = 0;

    dv->input_port = -1;

    dv->output_port = -1;

    dv->channel = -1;

    dv->raw1394 = raw1394_new_handle();

    if (!dv->raw1394) {

        av_log(context, AV_LOG_ERROR, "Failed to open IEEE1394 interface.\n");

        return AVERROR(EIO);

    }

    if ((nb_ports = raw1394_get_port_info(dv->raw1394, pinf, 16)) < 0) {

        av_log(context, AV_LOG_ERROR, "Failed to get number of IEEE1394 ports.\n");

        goto fail;

    }

    inport = strtol(context->filename, &endptr, 10);

    if (endptr != context->filename && *endptr == '\0') {

        av_log(context, AV_LOG_INFO, "Selecting IEEE1394 port: %d\n", inport);

        j = inport;

        nb_ports = inport + 1;

    } else if (strcmp(context->filename, "auto")) {

        av_log(context, AV_LOG_ERROR, "Invalid input \"%s\", you should specify "

               "\"auto\" for auto-detection, or the port number.\n", context->filename);

        goto fail;

    }

    if (dv->device_guid) {

        if (sscanf(dv->device_guid, "%llx", (long long unsigned int *)&guid) != 1) {

            av_log(context, AV_LOG_INFO, "Invalid dvguid parameter: %s\n",

                   dv->device_guid);

            goto fail;

        }

    }

    for (; j < nb_ports && port==-1; ++j) {

        raw1394_destroy_handle(dv->raw1394);

        if (!(dv->raw1394 = raw1394_new_handle_on_port(j))) {

            av_log(context, AV_LOG_ERROR, "Failed setting IEEE1394 port.\n");

            goto fail;

        }

        for (i=0; i<raw1394_get_nodecount(dv->raw1394); ++i) {

            /* Select device explicitly by GUID */

            if (guid > 1) {

                if (guid == rom1394_get_guid(dv->raw1394, i)) {

                    dv->node = i;

                    port = j;

                    break;

                }

            } else {

                /* Select first AV/C tape recorder player node */

                if (rom1394_get_directory(dv->raw1394, i, &rom_dir) < 0)

                    continue;

                if (((rom1394_get_node_type(&rom_dir) == ROM1394_NODE_TYPE_AVC) &&

                     avc1394_check_subunit_type(dv->raw1394, i, AVC1394_SUBUNIT_TYPE_VCR)) ||

                    (rom_dir.unit_spec_id == MOTDCT_SPEC_ID)) {

                    rom1394_free_directory(&rom_dir);

                    dv->node = i;

                    port = j;

                    break;

                }

                rom1394_free_directory(&rom_dir);

            }

        }

    }

    if (port == -1) {

        av_log(context, AV_LOG_ERROR, "No AV/C devices found.\n");

        goto fail;

    }

    /* Provide bus sanity for multiple connections */

    iec61883_cmp_normalize_output(dv->raw1394, 0xffc0 | dv->node);

    /* Find out if device is DV or HDV */

    if (dv->type == IEC61883_AUTO) {

        response = avc1394_transaction(dv->raw1394, dv->node,

                                       AVC1394_CTYPE_STATUS |

                                       AVC1394_SUBUNIT_TYPE_TAPE_RECORDER |

                                       AVC1394_SUBUNIT_ID_0 |

                                       AVC1394_VCR_COMMAND_OUTPUT_SIGNAL_MODE |

                                       0xFF, 2);

        response = AVC1394_GET_OPERAND0(response);

        dv->type = (response == 0x10 || response == 0x90 || response == 0x1A || response == 0x9A) ?

            IEC61883_HDV : IEC61883_DV;

    }

    /* Connect to device, and do initialization */

    dv->channel = iec61883_cmp_connect(dv->raw1394, dv->node, &dv->output_port,

                                       raw1394_get_local_id(dv->raw1394),

                                       &dv->input_port, &dv->bandwidth);

    if (dv->channel < 0)

        dv->channel = 63;

    if (!dv->max_packets)

        dv->max_packets = 100;

    if (CONFIG_MPEGTS_DEMUXER && dv->type == IEC61883_HDV) {

        /* Init HDV receive */

        avformat_new_stream(context, NULL);

        dv->mpeg_demux = avpriv_mpegts_parse_open(context);

        if (!dv->mpeg_demux)

            goto fail;

        dv->parse_queue = iec61883_parse_queue_hdv;

        dv->iec61883_mpeg2 = iec61883_mpeg2_recv_init(dv->raw1394,

                                                      (iec61883_mpeg2_recv_t)iec61883_callback,

                                                      dv);

        dv->max_packets *= 766;

    } else {

        /* Init DV receive */

        dv->dv_demux = avpriv_dv_init_demux(context);

        if (!dv->dv_demux)

            goto fail;

        dv->parse_queue = iec61883_parse_queue_dv;

        dv->iec61883_dv = iec61883_dv_fb_init(dv->raw1394, iec61883_callback, dv);

    }

    dv->raw1394_poll.fd = raw1394_get_fd(dv->raw1394);

    dv->raw1394_poll.events = POLLIN | POLLERR | POLLHUP | POLLPRI;

    /* Actually start receiving */

    if (dv->type == IEC61883_HDV)

        iec61883_mpeg2_recv_start(dv->iec61883_mpeg2, dv->channel);

    else

        iec61883_dv_fb_start(dv->iec61883_dv, dv->channel);

#if THREADS

    dv->thread_loop = 1;

    pthread_mutex_init(&dv->mutex, NULL);

    pthread_cond_init(&dv->cond, NULL);

    pthread_create(&dv->receive_task_thread, NULL, iec61883_receive_task, dv);

#endif

    return 0;

fail:

    raw1394_destroy_handle(dv->raw1394);

    return AVERROR(EIO);

}


static int aio_flush_f(BlockBackend *blk, int argc, char **argv)

{

    blk_drain_all();

    return 0;

}


static int idcin_decode_frame(AVCodecContext *avctx,

                              void *data, int *data_size,

                              AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    IdcinContext *s = avctx->priv_data;

    const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);

    s->buf = buf;

    s->size = buf_size;

    if (s->frame.data[0])

        avctx->release_buffer(avctx, &s->frame);

    if (avctx->get_buffer(avctx, &s->frame)) {

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

        return -1;

    }

    idcin_decode_vlcs(s);

    if (pal) {

        s->frame.palette_has_changed = 1;

        memcpy(s->pal, pal, AVPALETTE_SIZE);

    }

    /* make the palette available on the way out */

    memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);

    *data_size = sizeof(AVFrame);

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

    /* report that the buffer was completely consumed */

    return buf_size;

}


void vnc_display_open(DisplayState *ds, const char *display, Error **errp)

{

    VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;

    const char *options;

    int password = 0;

    int reverse = 0;

#ifdef CONFIG_VNC_TLS

    int tls = 0, x509 = 0;

#endif

#ifdef CONFIG_VNC_SASL

    int sasl = 0;

    int saslErr;

#endif

#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)

    int acl = 0;

#endif

    int lock_key_sync = 1;

    if (!vnc_display) {

        error_setg(errp, "VNC display not active");

        return;

    }

    vnc_display_close(ds);

    if (strcmp(display, "none") == 0)

        return;

    vs->display = g_strdup(display);

    vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;

    options = display;

    while ((options = strchr(options, ','))) {

        options++;

        if (strncmp(options, "password", 8) == 0) {

            if (fips_get_state()) {

                error_setg(errp,

                           "VNC password auth disabled due to FIPS mode, "

                           "consider using the VeNCrypt or SASL authentication "

                           "methods as an alternative");

                goto fail;

            }

            password = 1; /* Require password auth */

        } else if (strncmp(options, "reverse", 7) == 0) {

            reverse = 1;

        } else if (strncmp(options, "no-lock-key-sync", 16) == 0) {

            lock_key_sync = 0;

#ifdef CONFIG_VNC_SASL

        } else if (strncmp(options, "sasl", 4) == 0) {

            sasl = 1; /* Require SASL auth */

#endif

#ifdef CONFIG_VNC_WS

        } else if (strncmp(options, "websocket", 9) == 0) {

            char *start, *end;

            vs->websocket = 1;

            /* Check for 'websocket=<port>' */

            start = strchr(options, '=');

            end = strchr(options, ',');

            if (start && (!end || (start < end))) {

                int len = end ? end-(start+1) : strlen(start+1);

                if (len < 6) {

                    /* extract the host specification from display */

                    char  *host = NULL, *port = NULL, *host_end = NULL;

                    port = g_strndup(start + 1, len);

                    /* ipv6 hosts have colons */

                    end = strchr(display, ',');

                    host_end = g_strrstr_len(display, end - display, ":");

                    if (host_end) {

                        host = g_strndup(display, host_end - display + 1);

                    } else {

                        host = g_strndup(":", 1);

                    }

                    vs->ws_display = g_strconcat(host, port, NULL);

                    g_free(host);

                    g_free(port);

                }

            }

#endif /* CONFIG_VNC_WS */

#ifdef CONFIG_VNC_TLS

        } else if (strncmp(options, "tls", 3) == 0) {

            tls = 1; /* Require TLS */

        } else if (strncmp(options, "x509", 4) == 0) {

            char *start, *end;

            x509 = 1; /* Require x509 certificates */

            if (strncmp(options, "x509verify", 10) == 0)

                vs->tls.x509verify = 1; /* ...and verify client certs */

            /* Now check for 'x509=/some/path' postfix

             * and use that to setup x509 certificate/key paths */

            start = strchr(options, '=');

            end = strchr(options, ',');

            if (start && (!end || (start < end))) {

                int len = end ? end-(start+1) : strlen(start+1);

                char *path = g_strndup(start + 1, len);

                VNC_DEBUG("Trying certificate path '%s'\n", path);

                if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {

                    error_setg(errp, "Failed to find x509 certificates/keys in %s", path);

                    g_free(path);

                    goto fail;

                }

                g_free(path);

            } else {

                error_setg(errp, "No certificate path provided");

                goto fail;

            }

#endif

#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)

        } else if (strncmp(options, "acl", 3) == 0) {

            acl = 1;

#endif

        } else if (strncmp(options, "lossy", 5) == 0) {

            vs->lossy = true;

        } else if (strncmp(options, "non-adaptive", 12) == 0) {

            vs->non_adaptive = true;

        } else if (strncmp(options, "share=", 6) == 0) {

            if (strncmp(options+6, "ignore", 6) == 0) {

                vs->share_policy = VNC_SHARE_POLICY_IGNORE;

            } else if (strncmp(options+6, "allow-exclusive", 15) == 0) {

                vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;

            } else if (strncmp(options+6, "force-shared", 12) == 0) {

                vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;

            } else {

                error_setg(errp, "unknown vnc share= option");

                goto fail;

            }

        }

    }

#ifdef CONFIG_VNC_TLS

    if (acl && x509 && vs->tls.x509verify) {

        if (!(vs->tls.acl = qemu_acl_init("vnc.x509dname"))) {

            fprintf(stderr, "Failed to create x509 dname ACL\n");

            exit(1);

        }

    }

#endif

#ifdef CONFIG_VNC_SASL

    if (acl && sasl) {

        if (!(vs->sasl.acl = qemu_acl_init("vnc.username"))) {

            fprintf(stderr, "Failed to create username ACL\n");

            exit(1);

        }

    }

#endif

    /*

     * Combinations we support here:

     *

     *  - no-auth                (clear text, no auth)

     *  - password               (clear text, weak auth)

     *  - sasl                   (encrypt, good auth *IF* using Kerberos via GSSAPI)

     *  - tls                    (encrypt, weak anonymous creds, no auth)

     *  - tls + password         (encrypt, weak anonymous creds, weak auth)

     *  - tls + sasl             (encrypt, weak anonymous creds, good auth)

     *  - tls + x509             (encrypt, good x509 creds, no auth)

     *  - tls + x509 + password  (encrypt, good x509 creds, weak auth)

     *  - tls + x509 + sasl      (encrypt, good x509 creds, good auth)

     *

     * NB1. TLS is a stackable auth scheme.

     * NB2. the x509 schemes have option to validate a client cert dname

     */

    if (password) {

#ifdef CONFIG_VNC_TLS

        if (tls) {

            vs->auth = VNC_AUTH_VENCRYPT;

            if (x509) {

                VNC_DEBUG("Initializing VNC server with x509 password auth\n");

                vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;

            } else {

                VNC_DEBUG("Initializing VNC server with TLS password auth\n");

                vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;

            }

        } else {

#endif /* CONFIG_VNC_TLS */

            VNC_DEBUG("Initializing VNC server with password auth\n");

            vs->auth = VNC_AUTH_VNC;

#ifdef CONFIG_VNC_TLS

            vs->subauth = VNC_AUTH_INVALID;

        }

#endif /* CONFIG_VNC_TLS */

#ifdef CONFIG_VNC_SASL

    } else if (sasl) {

#ifdef CONFIG_VNC_TLS

        if (tls) {

            vs->auth = VNC_AUTH_VENCRYPT;

            if (x509) {

                VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");

                vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;

            } else {

                VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");

                vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;

            }

        } else {

#endif /* CONFIG_VNC_TLS */

            VNC_DEBUG("Initializing VNC server with SASL auth\n");

            vs->auth = VNC_AUTH_SASL;

#ifdef CONFIG_VNC_TLS

            vs->subauth = VNC_AUTH_INVALID;

        }

#endif /* CONFIG_VNC_TLS */

#endif /* CONFIG_VNC_SASL */

    } else {

#ifdef CONFIG_VNC_TLS

        if (tls) {

            vs->auth = VNC_AUTH_VENCRYPT;

            if (x509) {

                VNC_DEBUG("Initializing VNC server with x509 no auth\n");

                vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;

            } else {

                VNC_DEBUG("Initializing VNC server with TLS no auth\n");

                vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;

            }

        } else {

#endif

            VNC_DEBUG("Initializing VNC server with no auth\n");

            vs->auth = VNC_AUTH_NONE;

#ifdef CONFIG_VNC_TLS

            vs->subauth = VNC_AUTH_INVALID;

        }

#endif

    }

#ifdef CONFIG_VNC_SASL

    if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {

        error_setg(errp, "Failed to initialize SASL auth: %s",

                   sasl_errstring(saslErr, NULL, NULL));

        goto fail;

    }

#endif

    vs->lock_key_sync = lock_key_sync;

    if (reverse) {

        /* connect to viewer */

        int csock;

        vs->lsock = -1;

#ifdef CONFIG_VNC_WS

        vs->lwebsock = -1;

#endif

        if (strncmp(display, "unix:", 5) == 0) {

            csock = unix_connect(display+5, errp);

        } else {

            csock = inet_connect(display, errp);

        }

        if (csock < 0) {

            goto fail;

        }

        vnc_connect(vs, csock, 0, 0);

    } else {

        /* listen for connects */

        char *dpy;

        dpy = g_malloc(256);

        if (strncmp(display, "unix:", 5) == 0) {

            pstrcpy(dpy, 256, "unix:");

            vs->lsock = unix_listen(display+5, dpy+5, 256-5, errp);

        } else {

            vs->lsock = inet_listen(display, dpy, 256,

                                    SOCK_STREAM, 5900, errp);

            if (vs->lsock < 0) {

                g_free(dpy);

                goto fail;

            }

#ifdef CONFIG_VNC_WS

            if (vs->websocket) {

                if (vs->ws_display) {

                    vs->lwebsock = inet_listen(vs->ws_display, NULL, 256,

                        SOCK_STREAM, 0, errp);

                } else {

                    vs->lwebsock = inet_listen(vs->display, NULL, 256,

                        SOCK_STREAM, 5700, errp);

                }

                if (vs->lwebsock < 0) {

                    if (vs->lsock) {

                        close(vs->lsock);

                        vs->lsock = -1;

                    }

                    g_free(dpy);

                    goto fail;

                }

            }

#endif /* CONFIG_VNC_WS */

        }

        g_free(vs->display);

        vs->display = dpy;

        qemu_set_fd_handler2(vs->lsock, NULL,

                vnc_listen_regular_read, NULL, vs);

#ifdef CONFIG_VNC_WS

        if (vs->websocket) {

            qemu_set_fd_handler2(vs->lwebsock, NULL,

                    vnc_listen_websocket_read, NULL, vs);

        }

#endif /* CONFIG_VNC_WS */

    }

    return;

fail:

    g_free(vs->display);

    vs->display = NULL;

#ifdef CONFIG_VNC_WS

    g_free(vs->ws_display);

    vs->ws_display = NULL;

#endif /* CONFIG_VNC_WS */

}


bdrv_rw_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos,

                bool is_read)

{

    if (qemu_in_coroutine()) {

        return bdrv_co_rw_vmstate(bs, qiov, pos, is_read);

    } else {

        BdrvVmstateCo data = {

            .bs         = bs,

            .qiov       = qiov,

            .pos        = pos,

            .is_read    = is_read,

            .ret        = -EINPROGRESS,

        };

        Coroutine *co = qemu_coroutine_create(bdrv_co_rw_vmstate_entry, &data);

        qemu_coroutine_enter(co);

        while (data.ret == -EINPROGRESS) {

            aio_poll(bdrv_get_aio_context(bs), true);

        }

        return data.ret;

    }

}


static void exit_program(void)

{

    int i, j;

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

        avfilter_graph_free(&filtergraphs[i]->graph);

        for (j = 0; j < filtergraphs[i]->nb_inputs; j++) {

            av_freep(&filtergraphs[i]->inputs[j]->name);

            av_freep(&filtergraphs[i]->inputs[j]);

        }

        av_freep(&filtergraphs[i]->inputs);

        for (j = 0; j < filtergraphs[i]->nb_outputs; j++) {

            av_freep(&filtergraphs[i]->outputs[j]->name);

            av_freep(&filtergraphs[i]->outputs[j]);

        }

        av_freep(&filtergraphs[i]->outputs);

        av_freep(&filtergraphs[i]->graph_desc);

        av_freep(&filtergraphs[i]);

    }

    av_freep(&filtergraphs);

    /* close files */

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

        AVFormatContext *s = output_files[i]->ctx;

        if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE) && s->pb)

            avio_close(s->pb);

        avformat_free_context(s);

        av_dict_free(&output_files[i]->opts);

        av_freep(&output_files[i]);

    }

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

        AVBitStreamFilterContext *bsfc = output_streams[i]->bitstream_filters;

        while (bsfc) {

            AVBitStreamFilterContext *next = bsfc->next;

            av_bitstream_filter_close(bsfc);

            bsfc = next;

        }

        output_streams[i]->bitstream_filters = NULL;

        avcodec_free_frame(&output_streams[i]->filtered_frame);

        av_freep(&output_streams[i]->forced_keyframes);

        av_freep(&output_streams[i]->avfilter);

        av_freep(&output_streams[i]->logfile_prefix);

        av_freep(&output_streams[i]);

    }

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

        avformat_close_input(&input_files[i]->ctx);

        av_freep(&input_files[i]);

    }

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

        av_frame_free(&input_streams[i]->decoded_frame);

        av_frame_free(&input_streams[i]->filter_frame);

        av_dict_free(&input_streams[i]->opts);

        av_freep(&input_streams[i]->filters);

        av_freep(&input_streams[i]);

    }

    if (vstats_file)

        fclose(vstats_file);

    av_free(vstats_filename);

    av_freep(&input_streams);

    av_freep(&input_files);

    av_freep(&output_streams);

    av_freep(&output_files);

    uninit_opts();

    avformat_network_deinit();

    if (received_sigterm) {

        av_log(NULL, AV_LOG_INFO, "Received signal %d: terminating.\n",

               (int) received_sigterm);

        exit (255);

    }

}


static bool scsi_target_emulate_report_luns(SCSITargetReq *r)

{

    BusChild *kid;

    int i, len, n;

    int channel, id;

    bool found_lun0;

    if (r->req.cmd.xfer < 16) {

        return false;

    }

    if (r->req.cmd.buf[2] > 2) {

        return false;

    }

    channel = r->req.dev->channel;

    id = r->req.dev->id;

    found_lun0 = false;

    n = 0;

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

        DeviceState *qdev = kid->child;

        SCSIDevice *dev = SCSI_DEVICE(qdev);

        if (dev->channel == channel && dev->id == id) {

            if (dev->lun == 0) {

                found_lun0 = true;

            }

            n += 8;

        }

    }

    if (!found_lun0) {

        n += 8;

    }

    len = MIN(n + 8, r->req.cmd.xfer & ~7);

    if (len > sizeof(r->buf)) {

        /* TODO: > 256 LUNs? */

        return false;

    }

    memset(r->buf, 0, len);

    stl_be_p(&r->buf, n);

    i = found_lun0 ? 8 : 16;

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

        DeviceState *qdev = kid->child;

        SCSIDevice *dev = SCSI_DEVICE(qdev);

        if (dev->channel == channel && dev->id == id) {

            store_lun(&r->buf[i], dev->lun);

            i += 8;

        }

    }

    assert(i == n + 8);

    r->len = len;

    return true;

}


static int check_directory_consistency(BDRVVVFATState *s,

	int cluster_num, const char* path)

{

    int ret = 0;

    unsigned char* cluster = qemu_malloc(s->cluster_size);

    direntry_t* direntries = (direntry_t*)cluster;

    mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);

    long_file_name lfn;

    int path_len = strlen(path);

    char path2[PATH_MAX];

    assert(path_len < PATH_MAX); /* len was tested before! */

    pstrcpy(path2, sizeof(path2), path);

    path2[path_len] = '/';

    path2[path_len + 1] = '\0';

    if (mapping) {

	const char* basename = get_basename(mapping->path);

	const char* basename2 = get_basename(path);

	assert(mapping->mode & MODE_DIRECTORY);

	assert(mapping->mode & MODE_DELETED);

	mapping->mode &= ~MODE_DELETED;

	if (strcmp(basename, basename2))

	    schedule_rename(s, cluster_num, strdup(path));

    } else

	/* new directory */

	schedule_mkdir(s, cluster_num, strdup(path));

    lfn_init(&lfn);

    do {

	int i;

	int subret = 0;

	ret++;

	if (s->used_clusters[cluster_num] & USED_ANY) {

	    fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);

	    return 0;

	}

	s->used_clusters[cluster_num] = USED_DIRECTORY;

DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));

	subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,

		s->sectors_per_cluster);

	if (subret) {

	    fprintf(stderr, "Error fetching direntries\n");

	fail:

	    free(cluster);

	    return 0;

	}

	for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {

	    int cluster_count = 0;

DLOG(fprintf(stderr, "check direntry %d: \n", i); print_direntry(direntries + i));

	    if (is_volume_label(direntries + i) || is_dot(direntries + i) ||

		    is_free(direntries + i))

		continue;

	    subret = parse_long_name(&lfn, direntries + i);

	    if (subret < 0) {

		fprintf(stderr, "Error in long name\n");

		goto fail;

	    }

	    if (subret == 0 || is_free(direntries + i))

		continue;

	    if (fat_chksum(direntries+i) != lfn.checksum) {

		subret = parse_short_name(s, &lfn, direntries + i);

		if (subret < 0) {

		    fprintf(stderr, "Error in short name (%d)\n", subret);

		    goto fail;

		}

		if (subret > 0 || !strcmp((char*)lfn.name, ".")

			|| !strcmp((char*)lfn.name, ".."))

		    continue;

	    }

	    lfn.checksum = 0x100; /* cannot use long name twice */

	    if (path_len + 1 + lfn.len >= PATH_MAX) {

		fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);

		goto fail;

	    }

            pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,

                    (char*)lfn.name);

	    if (is_directory(direntries + i)) {

		if (begin_of_direntry(direntries + i) == 0) {

		    DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));

		    goto fail;

		}

		cluster_count = check_directory_consistency(s,

			begin_of_direntry(direntries + i), path2);

		if (cluster_count == 0) {

		    DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));

		    goto fail;

		}

	    } else if (is_file(direntries + i)) {

		/* check file size with FAT */

		cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);

		if (cluster_count !=

			(le32_to_cpu(direntries[i].size) + s->cluster_size

			 - 1) / s->cluster_size) {

		    DLOG(fprintf(stderr, "Cluster count mismatch\n"));

		    goto fail;

		}

	    } else

		assert(0); /* cluster_count = 0; */

	    ret += cluster_count;

	}

	cluster_num = modified_fat_get(s, cluster_num);

    } while(!fat_eof(s, cluster_num));

    free(cluster);

    return ret;

}


static int rpl_read_header(AVFormatContext *s)

{

    AVIOContext *pb = s->pb;

    RPLContext *rpl = s->priv_data;

    AVStream *vst = NULL, *ast = NULL;

    int total_audio_size;

    int error = 0;

    uint32_t i;

    int32_t audio_format, chunk_catalog_offset, number_of_chunks;

    AVRational fps;

    char line[RPL_LINE_LENGTH];

    // The header for RPL/ARMovie files is 21 lines of text

    // containing the various header fields.  The fields are always

    // in the same order, and other text besides the first

    // number usually isn't important.

    // (The spec says that there exists some significance

    // for the text in a few cases; samples needed.)

    error |= read_line(pb, line, sizeof(line));      // ARMovie

    error |= read_line(pb, line, sizeof(line));      // movie name

    av_dict_set(&s->metadata, "title"    , line, 0);

    error |= read_line(pb, line, sizeof(line));      // date/copyright

    av_dict_set(&s->metadata, "copyright", line, 0);

    error |= read_line(pb, line, sizeof(line));      // author and other

    av_dict_set(&s->metadata, "author"   , line, 0);

    // video headers

    vst = avformat_new_stream(s, NULL);

    if (!vst)

        return AVERROR(ENOMEM);

    vst->codec->codec_type      = AVMEDIA_TYPE_VIDEO;

    vst->codec->codec_tag       = read_line_and_int(pb, &error);  // video format

    vst->codec->width           = read_line_and_int(pb, &error);  // video width

    vst->codec->height          = read_line_and_int(pb, &error);  // video height

    vst->codec->bits_per_coded_sample = read_line_and_int(pb, &error);  // video bits per sample

    error |= read_line(pb, line, sizeof(line));                   // video frames per second

    fps = read_fps(line, &error);

    avpriv_set_pts_info(vst, 32, fps.den, fps.num);

    // Figure out the video codec

    switch (vst->codec->codec_tag) {

#if 0

        case 122:

            vst->codec->codec_id = AV_CODEC_ID_ESCAPE122;

            break;

#endif

        case 124:

            vst->codec->codec_id = AV_CODEC_ID_ESCAPE124;

            // The header is wrong here, at least sometimes

            vst->codec->bits_per_coded_sample = 16;

            break;

        case 130:

            vst->codec->codec_id = AV_CODEC_ID_ESCAPE130;

            break;

        default:

            avpriv_report_missing_feature(s, "Video format %i",

                                          vst->codec->codec_tag);

            vst->codec->codec_id = AV_CODEC_ID_NONE;

    }

    // Audio headers

    // ARMovie supports multiple audio tracks; I don't have any

    // samples, though. This code will ignore additional tracks.

    audio_format = read_line_and_int(pb, &error);  // audio format ID

    if (audio_format) {

        ast = avformat_new_stream(s, NULL);

        if (!ast)

            return AVERROR(ENOMEM);

        ast->codec->codec_type      = AVMEDIA_TYPE_AUDIO;

        ast->codec->codec_tag       = audio_format;

        ast->codec->sample_rate     = read_line_and_int(pb, &error);  // audio bitrate

        ast->codec->channels        = read_line_and_int(pb, &error);  // number of audio channels

        ast->codec->bits_per_coded_sample = read_line_and_int(pb, &error);  // audio bits per sample

        // At least one sample uses 0 for ADPCM, which is really 4 bits

        // per sample.

        if (ast->codec->bits_per_coded_sample == 0)

            ast->codec->bits_per_coded_sample = 4;

        ast->codec->bit_rate = ast->codec->sample_rate *

                               ast->codec->bits_per_coded_sample *

                               ast->codec->channels;

        ast->codec->codec_id = AV_CODEC_ID_NONE;

        switch (audio_format) {

            case 1:

                if (ast->codec->bits_per_coded_sample == 16) {

                    // 16-bit audio is always signed

                    ast->codec->codec_id = AV_CODEC_ID_PCM_S16LE;

                    break;

                }

                // There are some other formats listed as legal per the spec;

                // samples needed.

                break;

            case 101:

                if (ast->codec->bits_per_coded_sample == 8) {

                    // The samples with this kind of audio that I have

                    // are all unsigned.

                    ast->codec->codec_id = AV_CODEC_ID_PCM_U8;

                    break;

                } else if (ast->codec->bits_per_coded_sample == 4) {

                    ast->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_EA_SEAD;

                    break;

                }

                break;

        }

        if (ast->codec->codec_id == AV_CODEC_ID_NONE)

            avpriv_request_sample(s, "Audio format %i", audio_format);

        avpriv_set_pts_info(ast, 32, 1, ast->codec->bit_rate);

    } else {

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

            error |= read_line(pb, line, sizeof(line));

    }

    rpl->frames_per_chunk = read_line_and_int(pb, &error);  // video frames per chunk

    if (rpl->frames_per_chunk > 1 && vst->codec->codec_tag != 124)

        av_log(s, AV_LOG_WARNING,

               "Don't know how to split frames for video format %i. "

               "Video stream will be broken!\n", vst->codec->codec_tag);

    number_of_chunks = read_line_and_int(pb, &error);  // number of chunks in the file

    // The number in the header is actually the index of the last chunk.

    number_of_chunks++;

    error |= read_line(pb, line, sizeof(line));  // "even" chunk size in bytes

    error |= read_line(pb, line, sizeof(line));  // "odd" chunk size in bytes

    chunk_catalog_offset =                       // offset of the "chunk catalog"

        read_line_and_int(pb, &error);           //   (file index)

    error |= read_line(pb, line, sizeof(line));  // offset to "helpful" sprite

    error |= read_line(pb, line, sizeof(line));  // size of "helpful" sprite

    error |= read_line(pb, line, sizeof(line));  // offset to key frame list

    // Read the index

    avio_seek(pb, chunk_catalog_offset, SEEK_SET);

    total_audio_size = 0;

    for (i = 0; !error && i < number_of_chunks; i++) {

        int64_t offset, video_size, audio_size;

        error |= read_line(pb, line, sizeof(line));

        if (3 != sscanf(line, "%"SCNd64" , %"SCNd64" ; %"SCNd64,

                        &offset, &video_size, &audio_size))

            error = -1;

        av_add_index_entry(vst, offset, i * rpl->frames_per_chunk,

                           video_size, rpl->frames_per_chunk, 0);

        if (ast)

            av_add_index_entry(ast, offset + video_size, total_audio_size,

                               audio_size, audio_size * 8, 0);

        total_audio_size += audio_size * 8;

    }

    if (error) return AVERROR(EIO);

    return 0;

}


static void h264_free_context(PayloadContext *data)

{

#ifdef DEBUG

    int ii;

    for (ii = 0; ii < 32; ii++) {

        if (data->packet_types_received[ii])

            av_log(NULL, AV_LOG_DEBUG, "Received %d packets of type %d\n",

                   data->packet_types_received[ii], ii);

    }

#endif

    assert(data);

    assert(data->cookie == MAGIC_COOKIE);

    // avoid stale pointers (assert)

    data->cookie = DEAD_COOKIE;

    // and clear out this...

    av_free(data);

}


static void mirror_iteration_done(MirrorOp *op, int ret)

{

    MirrorBlockJob *s = op->s;

    struct iovec *iov;

    int64_t chunk_num;

    int i, nb_chunks, sectors_per_chunk;

    trace_mirror_iteration_done(s, op->sector_num, op->nb_sectors, ret);

    s->in_flight--;

    s->sectors_in_flight -= op->nb_sectors;

    iov = op->qiov.iov;

    for (i = 0; i < op->qiov.niov; i++) {

        MirrorBuffer *buf = (MirrorBuffer *) iov[i].iov_base;

        QSIMPLEQ_INSERT_TAIL(&s->buf_free, buf, next);

        s->buf_free_count++;

    }

    sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;

    chunk_num = op->sector_num / sectors_per_chunk;

    nb_chunks = DIV_ROUND_UP(op->nb_sectors, sectors_per_chunk);

    bitmap_clear(s->in_flight_bitmap, chunk_num, nb_chunks);

    if (ret >= 0) {

        if (s->cow_bitmap) {

            bitmap_set(s->cow_bitmap, chunk_num, nb_chunks);

        }

        s->common.offset += (uint64_t)op->nb_sectors * BDRV_SECTOR_SIZE;

    }

    qemu_iovec_destroy(&op->qiov);

    g_free(op);

    if (s->waiting_for_io) {

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

    }

}


static int find_image_range(int *pfirst_index, int *plast_index,

                            const char *path, int start_index)

{

    char buf[1024];

    int range, last_index, range1, first_index;

    /* find the first image */

    for (first_index = start_index; first_index < start_index + 5; first_index++) {

        if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0){

            *pfirst_index =

            *plast_index = 1;

            if (avio_check(buf, AVIO_FLAG_READ) > 0)

                return 0;

            return -1;

        }

        if (avio_check(buf, AVIO_FLAG_READ) > 0)

            break;

    }

    if (first_index == 5)

        goto fail;

    /* find the last image */

    last_index = first_index;

    for(;;) {

        range = 0;

        for(;;) {

            if (!range)

                range1 = 1;

            else

                range1 = 2 * range;

            if (av_get_frame_filename(buf, sizeof(buf), path,

                                      last_index + range1) < 0)

                goto fail;

            if (avio_check(buf, AVIO_FLAG_READ) <= 0)

                break;

            range = range1;

            /* just in case... */

            if (range >= (1 << 30))

                goto fail;

        }

        /* we are sure than image last_index + range exists */

        if (!range)

            break;

        last_index += range;

    }

    *pfirst_index = first_index;

    *plast_index = last_index;

    return 0;

 fail:

    return -1;

}


av_cold int ff_cavs_init(AVCodecContext *avctx)

{

    AVSContext *h = avctx->priv_data;

    ff_blockdsp_init(&h->bdsp, avctx);

    ff_h264chroma_init(&h->h264chroma, 8);

    ff_idctdsp_init(&h->idsp, avctx);

    ff_videodsp_init(&h->vdsp, 8);

    ff_cavsdsp_init(&h->cdsp, avctx);

    ff_init_scantable_permutation(h->idsp.idct_permutation,

                                  h->cdsp.idct_perm);

    ff_init_scantable(h->idsp.idct_permutation, &h->scantable, ff_zigzag_direct);

    h->avctx       = avctx;

    avctx->pix_fmt = AV_PIX_FMT_YUV420P;

    h->cur.f    = av_frame_alloc();

    h->DPB[0].f = av_frame_alloc();

    h->DPB[1].f = av_frame_alloc();

    if (!h->cur.f || !h->DPB[0].f || !h->DPB[1].f) {

        ff_cavs_end(avctx);

        return AVERROR(ENOMEM);

    }

    h->luma_scan[0]                     = 0;

    h->luma_scan[1]                     = 8;

    h->intra_pred_l[INTRA_L_VERT]       = intra_pred_vert;

    h->intra_pred_l[INTRA_L_HORIZ]      = intra_pred_horiz;

    h->intra_pred_l[INTRA_L_LP]         = intra_pred_lp;

    h->intra_pred_l[INTRA_L_DOWN_LEFT]  = intra_pred_down_left;

    h->intra_pred_l[INTRA_L_DOWN_RIGHT] = intra_pred_down_right;

    h->intra_pred_l[INTRA_L_LP_LEFT]    = intra_pred_lp_left;

    h->intra_pred_l[INTRA_L_LP_TOP]     = intra_pred_lp_top;

    h->intra_pred_l[INTRA_L_DC_128]     = intra_pred_dc_128;

    h->intra_pred_c[INTRA_C_LP]         = intra_pred_lp;

    h->intra_pred_c[INTRA_C_HORIZ]      = intra_pred_horiz;

    h->intra_pred_c[INTRA_C_VERT]       = intra_pred_vert;

    h->intra_pred_c[INTRA_C_PLANE]      = intra_pred_plane;

    h->intra_pred_c[INTRA_C_LP_LEFT]    = intra_pred_lp_left;

    h->intra_pred_c[INTRA_C_LP_TOP]     = intra_pred_lp_top;

    h->intra_pred_c[INTRA_C_DC_128]     = intra_pred_dc_128;

    h->mv[7]                            = un_mv;

    h->mv[19]                           = un_mv;

    return 0;

}


static int filter_packet(void *log_ctx, AVPacket *pkt,

                         AVFormatContext *fmt_ctx, AVBitStreamFilterContext *bsf_ctx)

{

    AVCodecContext *enc_ctx = fmt_ctx->streams[pkt->stream_index]->codec;

    int ret = 0;

    while (bsf_ctx) {

        AVPacket new_pkt = *pkt;

        ret = av_bitstream_filter_filter(bsf_ctx, enc_ctx, NULL,

                                             &new_pkt.data, &new_pkt.size,

                                             pkt->data, pkt->size,

                                             pkt->flags & AV_PKT_FLAG_KEY);

        if (ret == 0 && new_pkt.data != pkt->data && new_pkt.destruct) {

            if ((ret = av_copy_packet(&new_pkt, pkt)) < 0)

                break;

            ret = 1;

        }

        if (ret > 0) {

            av_free_packet(pkt);

            new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size,

                                           av_buffer_default_free, NULL, 0);

            if (!new_pkt.buf)

                break;

        }

        if (ret < 0) {

            av_log(log_ctx, AV_LOG_ERROR,

                "Failed to filter bitstream with filter %s for stream %d in file '%s' with codec %s\n",

                bsf_ctx->filter->name, pkt->stream_index, fmt_ctx->filename,

                avcodec_get_name(enc_ctx->codec_id));

        }

        *pkt = new_pkt;

        bsf_ctx = bsf_ctx->next;

    }

    return ret;

}


static void nbd_client_close(NBDClient *client)

{

    qemu_set_fd_handler2(client->sock, NULL, NULL, NULL, NULL);

    close(client->sock);

    client->sock = -1;

    if (client->close) {

        client->close(client);

    }

    nbd_client_put(client);

}


int avio_close(AVIOContext *s)

{

    AVIOInternal *internal;

    URLContext *h;

    if (!s)

        return 0;

    avio_flush(s);

    internal = s->opaque;

    h        = internal->h;

    av_opt_free(internal);

    av_freep(&internal->protocols);

    av_freep(&s->opaque);

    av_freep(&s->buffer);

    av_free(s);

    return ffurl_close(h);

}


int ff_jni_init_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfields_mapping, int global, void *log_ctx)
{
    int i, ret = 0;
    jclass last_clazz = NULL;
    for (i = 0; jfields_mapping[i].name; i++) {
        int mandatory = jfields_mapping[i].mandatory;
        enum FFJniFieldType type = jfields_mapping[i].type;
        if (type == FF_JNI_CLASS) {
            jclass clazz;
            last_clazz = NULL;
            clazz = (*env)->FindClass(env, jfields_mapping[i].name);
            if ((ret = ff_jni_exception_check(env, mandatory, log_ctx)) < 0 && mandatory) {
                goto done;
            last_clazz = *(jclass*)((uint8_t*)jfields + jfields_mapping[i].offset) =
                    global ? (*env)->NewGlobalRef(env, clazz) : clazz;
        } else {
            if (!last_clazz) {
                ret = AVERROR_EXTERNAL;
                break;
            switch(type) {
            case FF_JNI_FIELD: {
                jfieldID field_id = (*env)->GetFieldID(env, last_clazz, jfields_mapping[i].method, jfields_mapping[i].signature);
                if ((ret = ff_jni_exception_check(env, mandatory, log_ctx)) < 0 && mandatory) {
                    goto done;
                *(jfieldID*)((uint8_t*)jfields + jfields_mapping[i].offset) = field_id;
                break;
            case FF_JNI_STATIC_FIELD: {
                jfieldID field_id = (*env)->GetStaticFieldID(env, last_clazz, jfields_mapping[i].method, jfields_mapping[i].signature);
                if ((ret = ff_jni_exception_check(env, mandatory, log_ctx)) < 0 && mandatory) {
                    goto done;
                *(jfieldID*)((uint8_t*)jfields + jfields_mapping[i].offset) = field_id;
                break;
            case FF_JNI_METHOD: {
                jmethodID method_id = (*env)->GetMethodID(env, last_clazz, jfields_mapping[i].method, jfields_mapping[i].signature);
                if ((ret = ff_jni_exception_check(env, mandatory, log_ctx)) < 0 && mandatory) {
                    goto done;
                *(jmethodID*)((uint8_t*)jfields + jfields_mapping[i].offset) = method_id;
                break;
            case FF_JNI_STATIC_METHOD: {
                jmethodID method_id = (*env)->GetStaticMethodID(env, last_clazz, jfields_mapping[i].method, jfields_mapping[i].signature);
                if ((ret = ff_jni_exception_check(env, mandatory, log_ctx)) < 0 && mandatory) {
                    goto done;
                *(jmethodID*)((uint8_t*)jfields + jfields_mapping[i].offset) = method_id;
                break;
            default:
                av_log(log_ctx, AV_LOG_ERROR, "Unknown JNI field type\n");
                ret = AVERROR(EINVAL);
                goto done;
            ret = 0;
done:
    if (ret < 0) {
        /* reset jfields in case of failure so it does not leak references */
        ff_jni_reset_jfields(env, jfields, jfields_mapping, global, log_ctx);
    return ret;


static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,

        int64_t offset, unsigned int bytes, QEMUIOVector *qiov)

{

    BlockDriverState *bs = child->bs;

    /* Perform I/O through a temporary buffer so that users who scribble over

     * their read buffer while the operation is in progress do not end up

     * modifying the image file.  This is critical for zero-copy guest I/O

     * where anything might happen inside guest memory.

     */

    void *bounce_buffer;

    BlockDriver *drv = bs->drv;

    struct iovec iov;

    QEMUIOVector bounce_qiov;

    int64_t cluster_offset;

    unsigned int cluster_bytes;

    size_t skip_bytes;

    int ret;

    assert(child->perm & (BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE));

    /* Cover entire cluster so no additional backing file I/O is required when

     * allocating cluster in the image file.

     */

    bdrv_round_to_clusters(bs, offset, bytes, &cluster_offset, &cluster_bytes);

    trace_bdrv_co_do_copy_on_readv(bs, offset, bytes,

                                   cluster_offset, cluster_bytes);

    iov.iov_len = cluster_bytes;

    iov.iov_base = bounce_buffer = qemu_try_blockalign(bs, iov.iov_len);

    if (bounce_buffer == NULL) {

        ret = -ENOMEM;

        goto err;

    }

    qemu_iovec_init_external(&bounce_qiov, &iov, 1);

    ret = bdrv_driver_preadv(bs, cluster_offset, cluster_bytes,

                             &bounce_qiov, 0);

    if (ret < 0) {

        goto err;

    }

    if (drv->bdrv_co_pwrite_zeroes &&

        buffer_is_zero(bounce_buffer, iov.iov_len)) {

        /* FIXME: Should we (perhaps conditionally) be setting

         * BDRV_REQ_MAY_UNMAP, if it will allow for a sparser copy

         * that still correctly reads as zero? */

        ret = bdrv_co_do_pwrite_zeroes(bs, cluster_offset, cluster_bytes, 0);

    } else {

        /* This does not change the data on the disk, it is not necessary

         * to flush even in cache=writethrough mode.

         */

        ret = bdrv_driver_pwritev(bs, cluster_offset, cluster_bytes,

                                  &bounce_qiov, 0);

    }

    if (ret < 0) {

        /* It might be okay to ignore write errors for guest requests.  If this

         * is a deliberate copy-on-read then we don't want to ignore the error.

         * Simply report it in all cases.

         */

        goto err;

    }

    skip_bytes = offset - cluster_offset;

    qemu_iovec_from_buf(qiov, 0, bounce_buffer + skip_bytes, bytes);

err:

    qemu_vfree(bounce_buffer);

    return ret;

}


static int img_bench(int argc, char **argv)

{

    int c, ret = 0;

    const char *fmt = NULL, *filename;

    bool quiet = false;

    bool image_opts = false;

    bool is_write = false;

    int count = 75000;

    int depth = 64;

    int64_t offset = 0;

    size_t bufsize = 4096;

    int pattern = 0;

    size_t step = 0;

    int flush_interval = 0;

    bool drain_on_flush = true;

    int64_t image_size;

    BlockBackend *blk = NULL;

    BenchData data = {};

    int flags = 0;

    bool writethrough = false;

    struct timeval t1, t2;

    int i;

    for (;;) {

        static const struct option long_options[] = {

            {"help", no_argument, 0, 'h'},

            {"flush-interval", required_argument, 0, OPTION_FLUSH_INTERVAL},

            {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},

            {"pattern", required_argument, 0, OPTION_PATTERN},

            {"no-drain", no_argument, 0, OPTION_NO_DRAIN},

            {0, 0, 0, 0}

        };

        c = getopt_long(argc, argv, "hc:d:f:no:qs:S:t:w", long_options, NULL);

        if (c == -1) {

            break;

        }

        switch (c) {

        case 'h':

        case '?':

            help();

            break;

        case 'c':

        {

            unsigned long res;

            if (qemu_strtoul(optarg, NULL, 0, &res) < 0 || res > INT_MAX) {

                error_report("Invalid request count specified");

                return 1;

            }

            count = res;

            break;

        }

        case 'd':

        {

            unsigned long res;

            if (qemu_strtoul(optarg, NULL, 0, &res) < 0 || res > INT_MAX) {

                error_report("Invalid queue depth specified");

                return 1;

            }

            depth = res;

            break;

        }

        case 'f':

            fmt = optarg;

            break;

        case 'n':

            flags |= BDRV_O_NATIVE_AIO;

            break;

        case 'o':

        {

            offset = cvtnum(optarg);

            if (offset < 0) {

                error_report("Invalid offset specified");

                return 1;

            }

            break;

        }

            break;

        case 'q':

            quiet = true;

            break;

        case 's':

        {

            int64_t sval;

            sval = cvtnum(optarg);

            if (sval < 0 || sval > INT_MAX) {

                error_report("Invalid buffer size specified");

                return 1;

            }

            bufsize = sval;

            break;

        }

        case 'S':

        {

            int64_t sval;

            sval = cvtnum(optarg);

            if (sval < 0 || sval > INT_MAX) {

                error_report("Invalid step size specified");

                return 1;

            }

            step = sval;

            break;

        }

        case 't':

            ret = bdrv_parse_cache_mode(optarg, &flags, &writethrough);

            if (ret < 0) {

                error_report("Invalid cache mode");

                ret = -1;

                goto out;

            }

            break;

        case 'w':

            flags |= BDRV_O_RDWR;

            is_write = true;

            break;

        case OPTION_PATTERN:

        {

            unsigned long res;

            if (qemu_strtoul(optarg, NULL, 0, &res) < 0 || res > 0xff) {

                error_report("Invalid pattern byte specified");

                return 1;

            }

            pattern = res;

            break;

        }

        case OPTION_FLUSH_INTERVAL:

        {

            unsigned long res;

            if (qemu_strtoul(optarg, NULL, 0, &res) < 0 || res > INT_MAX) {

                error_report("Invalid flush interval specified");

                return 1;

            }

            flush_interval = res;

            break;

        }

        case OPTION_NO_DRAIN:

            drain_on_flush = false;

            break;

        case OPTION_IMAGE_OPTS:

            image_opts = true;

            break;

        }

    }

    if (optind != argc - 1) {

        error_exit("Expecting one image file name");

    }

    filename = argv[argc - 1];

    if (!is_write && flush_interval) {

        error_report("--flush-interval is only available in write tests");

        ret = -1;

        goto out;

    }

    if (flush_interval && flush_interval < depth) {

        error_report("Flush interval can't be smaller than depth");

        ret = -1;

        goto out;

    }

    blk = img_open(image_opts, filename, fmt, flags, writethrough, quiet);

    if (!blk) {

        ret = -1;

        goto out;

    }

    image_size = blk_getlength(blk);

    if (image_size < 0) {

        ret = image_size;

        goto out;

    }

    data = (BenchData) {

        .blk            = blk,

        .image_size     = image_size,

        .bufsize        = bufsize,

        .step           = step ?: bufsize,

        .nrreq          = depth,

        .n              = count,

        .offset         = offset,

        .write          = is_write,

        .flush_interval = flush_interval,

        .drain_on_flush = drain_on_flush,

    };

    printf("Sending %d %s requests, %d bytes each, %d in parallel "

           "(starting at offset %" PRId64 ", step size %d)\n",

           data.n, data.write ? "write" : "read", data.bufsize, data.nrreq,

           data.offset, data.step);

    if (flush_interval) {

        printf("Sending flush every %d requests\n", flush_interval);

    }

    data.buf = blk_blockalign(blk, data.nrreq * data.bufsize);

    memset(data.buf, pattern, data.nrreq * data.bufsize);

    data.qiov = g_new(QEMUIOVector, data.nrreq);

    for (i = 0; i < data.nrreq; i++) {

        qemu_iovec_init(&data.qiov[i], 1);

        qemu_iovec_add(&data.qiov[i],

                       data.buf + i * data.bufsize, data.bufsize);

    }

    gettimeofday(&t1, NULL);

    bench_cb(&data, 0);

    while (data.n > 0) {

        main_loop_wait(false);

    }

    gettimeofday(&t2, NULL);

    printf("Run completed in %3.3f seconds.\n",

           (t2.tv_sec - t1.tv_sec)

           + ((double)(t2.tv_usec - t1.tv_usec) / 1000000));

out:

    qemu_vfree(data.buf);

    blk_unref(blk);

    if (ret) {

        return 1;

    }

    return 0;

}


void object_property_add_link(Object *obj, const char *name,

                              const char *type, Object **child,

                              Error **errp)

{

    gchar *full_type;

    full_type = g_strdup_printf("link<%s>", type);

    object_property_add(obj, name, full_type,

                        object_get_link_property,

                        object_set_link_property,

                        NULL, child, errp);

    g_free(full_type);

}


static void process_event(JSONMessageParser *parser, QList *tokens)

{

    GAState *s = container_of(parser, GAState, parser);

    QObject *obj;

    QDict *qdict;

    Error *err = NULL;

    int ret;

    g_assert(s && parser);

    g_debug("process_event: called");

    obj = json_parser_parse_err(tokens, NULL, &err);

    if (err || !obj || qobject_type(obj) != QTYPE_QDICT) {

        qobject_decref(obj);

        qdict = qdict_new();

        if (!err) {

            g_warning("failed to parse event: unknown error");

            error_setg(&err, QERR_JSON_PARSING);

        } else {

            g_warning("failed to parse event: %s", error_get_pretty(err));

        }

        qdict_put_obj(qdict, "error", qmp_build_error_object(err));

        error_free(err);

    } else {

        qdict = qobject_to_qdict(obj);

    }

    g_assert(qdict);

    /* handle host->guest commands */

    if (qdict_haskey(qdict, "execute")) {

        process_command(s, qdict);

    } else {

        if (!qdict_haskey(qdict, "error")) {

            QDECREF(qdict);

            qdict = qdict_new();

            g_warning("unrecognized payload format");

            error_setg(&err, QERR_UNSUPPORTED);

            qdict_put_obj(qdict, "error", qmp_build_error_object(err));

            error_free(err);

        }

        ret = send_response(s, QOBJECT(qdict));

        if (ret < 0) {

            g_warning("error sending error response: %s", strerror(-ret));

        }

    }

    QDECREF(qdict);

}


static inline void RENAME(rgb32tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)

{

    uint8_t *dest = dst;

    const uint8_t *s = src;

    const uint8_t *end;

    const uint8_t *mm_end;

    end = s + src_size;

    __asm__ volatile(PREFETCH"    %0"::"m"(*s):"memory");

    mm_end = end - 31;

    while (s < mm_end) {

        __asm__ volatile(

            PREFETCH"    32%1           \n\t"

            "movq          %1, %%mm0    \n\t"

            "movq         8%1, %%mm1    \n\t"

            "movq        16%1, %%mm4    \n\t"

            "movq        24%1, %%mm5    \n\t"

            "movq       %%mm0, %%mm2    \n\t"

            "movq       %%mm1, %%mm3    \n\t"

            "movq       %%mm4, %%mm6    \n\t"

            "movq       %%mm5, %%mm7    \n\t"

            STORE_BGR24_MMX

            :"=m"(*dest)

            :"m"(*s)

            :"memory");

        dest += 24;

        s += 32;

    }

    __asm__ volatile(SFENCE:::"memory");

    __asm__ volatile(EMMS:::"memory");

    while (s < end) {

        *dest++ = *s++;

        *dest++ = *s++;

        *dest++ = *s++;

        s++;

    }

}


static void slice_thread_park_workers(ThreadContext *c)

{

    pthread_cond_wait(&c->last_job_cond, &c->current_job_lock);

    pthread_mutex_unlock(&c->current_job_lock);

}


static av_cold int ljpeg_encode_init(AVCodecContext *avctx)

{

    LJpegEncContext *s = avctx->priv_data;

    int chroma_v_shift, chroma_h_shift;

    if ((avctx->pix_fmt == AV_PIX_FMT_YUV420P ||

         avctx->pix_fmt == AV_PIX_FMT_YUV422P ||

         avctx->pix_fmt == AV_PIX_FMT_YUV444P) &&

        avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {

        av_log(avctx, AV_LOG_ERROR,

               "Limited range YUV is non-standard, set strict_std_compliance to "

               "at least unofficial to use it.\n");

        return AVERROR(EINVAL);

    }

    avctx->coded_frame = av_frame_alloc();

    if (!avctx->coded_frame)

        return AVERROR(ENOMEM);

    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;

    avctx->coded_frame->key_frame = 1;

    s->scratch = av_malloc_array(avctx->width + 1, sizeof(*s->scratch));

    ff_dsputil_init(&s->dsp, avctx);

    ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct);

    av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift,

                                     &chroma_v_shift);

    if (avctx->pix_fmt   == AV_PIX_FMT_BGR24) {

        s->vsample[0] = s->hsample[0] =

        s->vsample[1] = s->hsample[1] =

        s->vsample[2] = s->hsample[2] = 1;

    } else {

        s->vsample[0] = 2;

        s->vsample[1] = 2 >> chroma_v_shift;

        s->vsample[2] = 2 >> chroma_v_shift;

        s->hsample[0] = 2;

        s->hsample[1] = 2 >> chroma_h_shift;

        s->hsample[2] = 2 >> chroma_h_shift;

    }

    ff_mjpeg_build_huffman_codes(s->huff_size_dc_luminance,

                                 s->huff_code_dc_luminance,

                                 avpriv_mjpeg_bits_dc_luminance,

                                 avpriv_mjpeg_val_dc);

    ff_mjpeg_build_huffman_codes(s->huff_size_dc_chrominance,

                                 s->huff_code_dc_chrominance,

                                 avpriv_mjpeg_bits_dc_chrominance,

                                 avpriv_mjpeg_val_dc);

    return 0;

}


static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,

                                         const char *name, int devfn,

                                         Error **errp)

{

    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);

    PCIConfigReadFunc *config_read = pc->config_read;

    PCIConfigWriteFunc *config_write = pc->config_write;

    Error *local_err = NULL;

    AddressSpace *dma_as;

    DeviceState *dev = DEVICE(pci_dev);

    pci_dev->bus = bus;

    /* Only pci bridges can be attached to extra PCI root buses */

    if (pci_bus_is_root(bus) && bus->parent_dev && !pc->is_bridge) {

        error_setg(errp,

                   "PCI: Only PCI/PCIe bridges can be plugged into %s",

                    bus->parent_dev->name);

        return NULL;

    }

    if (devfn < 0) {

        for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);

            devfn += PCI_FUNC_MAX) {

            if (!bus->devices[devfn])

                goto found;

        }

        error_setg(errp, "PCI: no slot/function available for %s, all in use",

                   name);

        return NULL;

    found: ;

    } else if (bus->devices[devfn]) {

        error_setg(errp, "PCI: slot %d function %d not available for %s,"

                   " in use by %s",

                   PCI_SLOT(devfn), PCI_FUNC(devfn), name,

                   bus->devices[devfn]->name);

        return NULL;

    } else if (dev->hotplugged &&

               pci_get_function_0(pci_dev)) {

        error_setg(errp, "PCI: slot %d function 0 already ocuppied by %s,"

                   " new func %s cannot be exposed to guest.",

                   PCI_SLOT(devfn),

                   bus->devices[PCI_DEVFN(PCI_SLOT(devfn), 0)]->name,

                   name);

       return NULL;

    }

    pci_dev->devfn = devfn;

    dma_as = pci_device_iommu_address_space(pci_dev);

    memory_region_init_alias(&pci_dev->bus_master_enable_region,

                             OBJECT(pci_dev), "bus master",

                             dma_as->root, 0, memory_region_size(dma_as->root));

    memory_region_set_enabled(&pci_dev->bus_master_enable_region, false);

    address_space_init(&pci_dev->bus_master_as, &pci_dev->bus_master_enable_region,

                       name);

    pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);

    pci_dev->irq_state = 0;

    pci_config_alloc(pci_dev);

    pci_config_set_vendor_id(pci_dev->config, pc->vendor_id);

    pci_config_set_device_id(pci_dev->config, pc->device_id);

    pci_config_set_revision(pci_dev->config, pc->revision);

    pci_config_set_class(pci_dev->config, pc->class_id);

    if (!pc->is_bridge) {

        if (pc->subsystem_vendor_id || pc->subsystem_id) {

            pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID,

                         pc->subsystem_vendor_id);

            pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID,

                         pc->subsystem_id);

        } else {

            pci_set_default_subsystem_id(pci_dev);

        }

    } else {

        /* subsystem_vendor_id/subsystem_id are only for header type 0 */

        assert(!pc->subsystem_vendor_id);

        assert(!pc->subsystem_id);

    }

    pci_init_cmask(pci_dev);

    pci_init_wmask(pci_dev);

    pci_init_w1cmask(pci_dev);

    if (pc->is_bridge) {

        pci_init_mask_bridge(pci_dev);

    }

    pci_init_multifunction(bus, pci_dev, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        do_pci_unregister_device(pci_dev);

        return NULL;

    }

    if (!config_read)

        config_read = pci_default_read_config;

    if (!config_write)

        config_write = pci_default_write_config;

    pci_dev->config_read = config_read;

    pci_dev->config_write = config_write;

    bus->devices[devfn] = pci_dev;

    pci_dev->version_id = 2; /* Current pci device vmstate version */

    return pci_dev;

}


static void multiwrite_cb(void *opaque, int ret)

{

    MultiwriteCB *mcb = opaque;

    if (ret < 0) {

        mcb->error = ret;

        multiwrite_user_cb(mcb);

    }

    mcb->num_requests--;

    if (mcb->num_requests == 0) {

        if (mcb->error == 0) {

            multiwrite_user_cb(mcb);

        }

        qemu_free(mcb);

    }

}


qemu_irq *pl190_init(uint32_t base, qemu_irq irq, qemu_irq fiq)

{

    pl190_state *s;

    qemu_irq *qi;

    int iomemtype;

    s = (pl190_state *)qemu_mallocz(sizeof(pl190_state));

    iomemtype = cpu_register_io_memory(0, pl190_readfn,

                                       pl190_writefn, s);

    cpu_register_physical_memory(base, 0x00000fff, iomemtype);

    qi = qemu_allocate_irqs(pl190_set_irq, s, 32);

    s->base = base;

    s->irq = irq;

    s->fiq = fiq;

    pl190_reset(s);

    /* ??? Save/restore.  */

    return qi;

}


static void pci_reg_write4(void *opaque, target_phys_addr_t addr,

                               uint32_t value)

{

    PPCE500PCIState *pci = opaque;

    unsigned long win;

    win = addr & 0xfe0;

    pci_debug("%s: value:%x -> win:%lx(addr:" TARGET_FMT_plx ")\n",

              __func__, value, win, addr);

    switch (win) {

    case PPCE500_PCI_OW1:

    case PPCE500_PCI_OW2:

    case PPCE500_PCI_OW3:

    case PPCE500_PCI_OW4:

        switch (addr & 0xC) {

        case PCI_POTAR:

            pci->pob[(addr >> 5) & 0x7].potar = value;

            break;

        case PCI_POTEAR:

            pci->pob[(addr >> 5) & 0x7].potear = value;

            break;

        case PCI_POWBAR:

            pci->pob[(addr >> 5) & 0x7].powbar = value;

            break;

        case PCI_POWAR:

            pci->pob[(addr >> 5) & 0x7].powar = value;

            break;

        default:

            break;

        };

        break;

    case PPCE500_PCI_IW3:

    case PPCE500_PCI_IW2:

    case PPCE500_PCI_IW1:

        switch (addr & 0xC) {

        case PCI_PITAR:

            pci->pib[(addr >> 5) & 0x3].pitar = value;

            break;

        case PCI_PIWBAR:

            pci->pib[(addr >> 5) & 0x3].piwbar = value;

            break;

        case PCI_PIWBEAR:

            pci->pib[(addr >> 5) & 0x3].piwbear = value;

            break;

        case PCI_PIWAR:

            pci->pib[(addr >> 5) & 0x3].piwar = value;

            break;

        default:

            break;

        };

        break;

    case PPCE500_PCI_GASKET_TIMR:

        pci->gasket_time = value;

        break;

    default:

        break;

    };

}


static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,

                                  uint64_t pictx, bool bsr)

{

    XHCISlot *slot;

    USBPort *uport;

    USBDevice *dev;

    dma_addr_t ictx, octx, dcbaap;

    uint64_t poctx;

    uint32_t ictl_ctx[2];

    uint32_t slot_ctx[4];

    uint32_t ep0_ctx[5];

    int i;

    TRBCCode res;

    assert(slotid >= 1 && slotid <= xhci->numslots);

    dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high);

    poctx = ldq_le_pci_dma(PCI_DEVICE(xhci), dcbaap + 8 * slotid);

    ictx = xhci_mask64(pictx);

    octx = xhci_mask64(poctx);

    DPRINTF("xhci: input context at "DMA_ADDR_FMT"\n", ictx);

    DPRINTF("xhci: output context at "DMA_ADDR_FMT"\n", octx);

    xhci_dma_read_u32s(xhci, ictx, ictl_ctx, sizeof(ictl_ctx));

    if (ictl_ctx[0] != 0x0 || ictl_ctx[1] != 0x3) {

        fprintf(stderr, "xhci: invalid input context control %08x %08x\n",

                ictl_ctx[0], ictl_ctx[1]);

        return CC_TRB_ERROR;

    }

    xhci_dma_read_u32s(xhci, ictx+32, slot_ctx, sizeof(slot_ctx));

    xhci_dma_read_u32s(xhci, ictx+64, ep0_ctx, sizeof(ep0_ctx));

    DPRINTF("xhci: input slot context: %08x %08x %08x %08x\n",

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

    DPRINTF("xhci: input ep0 context: %08x %08x %08x %08x %08x\n",

            ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]);

    uport = xhci_lookup_uport(xhci, slot_ctx);

    if (uport == NULL) {

        fprintf(stderr, "xhci: port not found\n");

        return CC_TRB_ERROR;

    }

    trace_usb_xhci_slot_address(slotid, uport->path);

    dev = uport->dev;

    if (!dev) {

        fprintf(stderr, "xhci: port %s not connected\n", uport->path);

        return CC_USB_TRANSACTION_ERROR;

    }

    for (i = 0; i < xhci->numslots; i++) {

        if (i == slotid-1) {

            continue;

        }

        if (xhci->slots[i].uport == uport) {

            fprintf(stderr, "xhci: port %s already assigned to slot %d\n",

                    uport->path, i+1);

            return CC_TRB_ERROR;

        }

    }

    slot = &xhci->slots[slotid-1];

    slot->uport = uport;

    slot->ctx = octx;

    if (bsr) {

        slot_ctx[3] = SLOT_DEFAULT << SLOT_STATE_SHIFT;

    } else {

        USBPacket p;

        uint8_t buf[1];

        slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slotid;

        usb_device_reset(dev);

        memset(&p, 0, sizeof(p));

        usb_packet_addbuf(&p, buf, sizeof(buf));

        usb_packet_setup(&p, USB_TOKEN_OUT,

                         usb_ep_get(dev, USB_TOKEN_OUT, 0), 0,

                         0, false, false);

        usb_device_handle_control(dev, &p,

                                  DeviceOutRequest | USB_REQ_SET_ADDRESS,

                                  slotid, 0, 0, NULL);

        assert(p.status != USB_RET_ASYNC);

    }

    res = xhci_enable_ep(xhci, slotid, 1, octx+32, ep0_ctx);

    DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n",

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

    DPRINTF("xhci: output ep0 context: %08x %08x %08x %08x %08x\n",

            ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]);

    xhci_dma_write_u32s(xhci, octx, slot_ctx, sizeof(slot_ctx));

    xhci_dma_write_u32s(xhci, octx+32, ep0_ctx, sizeof(ep0_ctx));

    xhci->slots[slotid-1].addressed = 1;

    return res;

}


static void encode_frame(MpegAudioContext *s,

                         unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT],

                         int padding)

{

    int i, j, k, l, bit_alloc_bits, b, ch;

    unsigned char *sf;

    int q[3];

    PutBitContext *p = &s->pb;

    /* header */

    put_bits(p, 12, 0xfff);

    put_bits(p, 1, 1 - s->lsf); /* 1 = mpeg1 ID, 0 = mpeg2 lsf ID */

    put_bits(p, 2, 4-2);  /* layer 2 */

    put_bits(p, 1, 1); /* no error protection */

    put_bits(p, 4, s->bitrate_index);

    put_bits(p, 2, s->freq_index);

    put_bits(p, 1, s->do_padding); /* use padding */

    put_bits(p, 1, 0);             /* private_bit */

    put_bits(p, 2, s->nb_channels == 2 ? MPA_STEREO : MPA_MONO);

    put_bits(p, 2, 0); /* mode_ext */

    put_bits(p, 1, 0); /* no copyright */

    put_bits(p, 1, 1); /* original */

    put_bits(p, 2, 0); /* no emphasis */

    /* bit allocation */

    j = 0;

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

        bit_alloc_bits = s->alloc_table[j];

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

            put_bits(p, bit_alloc_bits, bit_alloc[ch][i]);

        }

        j += 1 << bit_alloc_bits;

    }

    /* scale codes */

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

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

            if (bit_alloc[ch][i])

                put_bits(p, 2, s->scale_code[ch][i]);

        }

    }

    /* scale factors */

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

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

            if (bit_alloc[ch][i]) {

                sf = &s->scale_factors[ch][i][0];

                switch(s->scale_code[ch][i]) {

                case 0:

                    put_bits(p, 6, sf[0]);

                    put_bits(p, 6, sf[1]);

                    put_bits(p, 6, sf[2]);

                    break;

                case 3:

                case 1:

                    put_bits(p, 6, sf[0]);

                    put_bits(p, 6, sf[2]);

                    break;

                case 2:

                    put_bits(p, 6, sf[0]);

                    break;

                }

            }

        }

    }

    /* quantization & write sub band samples */

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

        for(l=0;l<12;l+=3) {

            j = 0;

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

                bit_alloc_bits = s->alloc_table[j];

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

                    b = bit_alloc[ch][i];

                    if (b) {

                        int qindex, steps, m, sample, bits;

                        /* we encode 3 sub band samples of the same sub band at a time */

                        qindex = s->alloc_table[j+b];

                        steps = ff_mpa_quant_steps[qindex];

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

                            sample = s->sb_samples[ch][k][l + m][i];

                            /* divide by scale factor */

#if USE_FLOATS

                            {

                                float a;

                                a = (float)sample * s->scale_factor_inv_table[s->scale_factors[ch][i][k]];

                                q[m] = (int)((a + 1.0) * steps * 0.5);

                            }

#else

                            {

                                int q1, e, shift, mult;

                                e = s->scale_factors[ch][i][k];

                                shift = s->scale_factor_shift[e];

                                mult = s->scale_factor_mult[e];

                                /* normalize to P bits */

                                if (shift < 0)

                                    q1 = sample << (-shift);

                                else

                                    q1 = sample >> shift;

                                q1 = (q1 * mult) >> P;

                                q1 += 1 << P;

                                if (q1 < 0)

                                    q1 = 0;

                                q[m] = (unsigned)(q1 * steps) >> (P + 1);

                            }

#endif

                            if (q[m] >= steps)

                                q[m] = steps - 1;

                            av_assert2(q[m] >= 0 && q[m] < steps);

                        }

                        bits = ff_mpa_quant_bits[qindex];

                        if (bits < 0) {

                            /* group the 3 values to save bits */

                            put_bits(p, -bits,

                                     q[0] + steps * (q[1] + steps * q[2]));

                        } else {

                            put_bits(p, bits, q[0]);

                            put_bits(p, bits, q[1]);

                            put_bits(p, bits, q[2]);

                        }

                    }

                }

                /* next subband in alloc table */

                j += 1 << bit_alloc_bits;

            }

        }

    }

    /* padding */

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

        put_bits(p, 1, 0);

    /* flush */

    flush_put_bits(p);

}


static int quantize_coefs(double *coef, int *idx, float *lpc, int order)

{

    int i;

    uint8_t u_coef;

    const float *quant_arr = tns_tmp2_map[TNS_Q_BITS == 4];

    const double iqfac_p = ((1 << (TNS_Q_BITS-1)) - 0.5)/(M_PI/2.0);

    const double iqfac_m = ((1 << (TNS_Q_BITS-1)) + 0.5)/(M_PI/2.0);

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

        idx[i] = ceilf(asin(coef[i])*((coef[i] >= 0) ? iqfac_p : iqfac_m));

        u_coef = (idx[i])&(~(~0<<TNS_Q_BITS));

        lpc[i] = quant_arr[u_coef];

    }

    return order;

}


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

{

    int16_t *v = pv;

    qemu_get_sbe16s(f, v);

    return 0;

}


static void compress_to_network(RDMACompress *comp)

{

    comp->value = htonl(comp->value);

    comp->block_idx = htonl(comp->block_idx);

    comp->offset = htonll(comp->offset);

    comp->length = htonll(comp->length);

}


int avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)

{

    graph->filters = av_realloc(graph->filters,

                                sizeof(AVFilterContext*) * ++graph->filter_count);

    if (!graph->filters)

        return AVERROR(ENOMEM);

    graph->filters[graph->filter_count - 1] = filter;

    return 0;

}