static void align_position(AVIOContext *pb,  int64_t offset, uint64_t size)

{

    if (avio_tell(pb) != offset + size)

        avio_seek(pb, offset + size, SEEK_SET);

}


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

{

    USBSerialState *s = (USBSerialState *)dev;

    int ret = 0;

    uint8_t devep = p->devep;

    uint8_t *data = p->data;

    int len = p->len;

    int first_len;

    switch (p->pid) {

    case USB_TOKEN_OUT:

        if (devep != 2)

            goto fail;

        qemu_chr_write(s->cs, data, len);

        break;

    case USB_TOKEN_IN:

        if (devep != 1)

            goto fail;

        first_len = RECV_BUF - s->recv_ptr;

        if (len <= 2) {

            ret = USB_RET_NAK;

            break;

        }

        *data++ = usb_get_modem_lines(s) | 1;

        /* We do not have the uart details */

        /* handle serial break */

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

            s->event_trigger &= ~FTDI_BI;

            *data = FTDI_BI;

            ret = 2;

            break;

        } else {

            *data++ = 0;

        }

        len -= 2;

        if (len > s->recv_used)

            len = s->recv_used;

        if (!len) {

            ret = USB_RET_NAK;

            break;

        }

        if (first_len > len)

            first_len = len;

        memcpy(data, s->recv_buf + s->recv_ptr, first_len);

        if (len > first_len)

            memcpy(data + first_len, s->recv_buf, len - first_len);

        s->recv_used -= len;

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

        ret = len + 2;

        break;

    default:

        DPRINTF("Bad token\n");

    fail:

        ret = USB_RET_STALL;

        break;

    }

    return ret;

}


void isa_register_portio_list(ISADevice *dev, uint16_t start,

                              const MemoryRegionPortio *pio_start,

                              void *opaque, const char *name)

{

    PortioList piolist;

    /* START is how we should treat DEV, regardless of the actual

       contents of the portio array.  This is how the old code

       actually handled e.g. the FDC device.  */

    isa_init_ioport(dev, start);

    /* FIXME: the device should store created PortioList in its state.  Note

       that DEV can be NULL here and that single device can register several

       portio lists.  Current implementation is leaking memory allocated

       in portio_list_init.  The leak is not critical because it happens only

       at initialization time.  */

    portio_list_init(&piolist, OBJECT(dev), pio_start, opaque, name);

    portio_list_add(&piolist, isabus->address_space_io, start);

}


static inline void write_mem(IVState *s, uint64_t off,

                             const void *buf, size_t len)

{

    QTestState *qtest = global_qtest;

    global_qtest = s->qtest;

    qpci_memwrite(s->dev, s->mem_base + off, buf, len);

    global_qtest = qtest;

}


static void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)

{

    QEMUTimer **pt, *t;

    qemu_del_timer(ts);

    /* add the timer in the sorted list */

    /* NOTE: this code must be signal safe because

       qemu_timer_expired() can be called from a signal. */

    pt = &active_timers[ts->clock->type];

    for(;;) {

        t = *pt;

        if (!t)

            break;

        if (t->expire_time > expire_time)

            break;

        pt = &t->next;

    }

    ts->expire_time = expire_time;

    ts->next = *pt;

    *pt = ts;

    /* Rearm if necessary  */

    if (pt == &active_timers[ts->clock->type]) {

        if (!alarm_timer->pending) {

            qemu_rearm_alarm_timer(alarm_timer);

        }

        /* Interrupt execution to force deadline recalculation.  */

        if (use_icount)

            qemu_notify_event();

    }

}


static void co_read_response(void *opaque)

{

    BDRVSheepdogState *s = opaque;

    if (!s->co_recv) {

        s->co_recv = qemu_coroutine_create(aio_read_response);

    }

    qemu_coroutine_enter(s->co_recv, opaque);

}


static void omap2_inth_write(void *opaque, target_phys_addr_t addr,

                             uint64_t value, unsigned size)

{

    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;

    int offset = addr;

    int bank_no, line_no;

    struct omap_intr_handler_bank_s *bank = NULL;

    if ((offset & 0xf80) == 0x80) {

        bank_no = (offset & 0x60) >> 5;

        if (bank_no < s->nbanks) {

            offset &= ~0x60;

            bank = &s->bank[bank_no];

        }

    }

    switch (offset) {

    case 0x10:	/* INTC_SYSCONFIG */

        s->autoidle &= 4;

        s->autoidle |= (value & 1) << 2;

        if (value & 2)						/* SOFTRESET */

            omap_inth_reset(&s->busdev.qdev);

    case 0x48:	/* INTC_CONTROL */

        s->mask = (value & 4) ? 0 : ~0;				/* GLOBALMASK */

        if (value & 2) {					/* NEWFIQAGR */

            qemu_set_irq(s->parent_intr[1], 0);

            s->new_agr[1] = ~0;

            omap_inth_update(s, 1);

        }

        if (value & 1) {					/* NEWIRQAGR */

            qemu_set_irq(s->parent_intr[0], 0);

            s->new_agr[0] = ~0;

            omap_inth_update(s, 0);

        }

    case 0x4c:	/* INTC_PROTECTION */

        /* TODO: Make a bitmap (or sizeof(char)map) of access privileges

         * for every register, see Chapter 3 and 4 for privileged mode.  */

        if (value & 1)

            fprintf(stderr, "%s: protection mode enable attempt\n",

                            __FUNCTION__);

    case 0x50:	/* INTC_IDLE */

        s->autoidle &= ~3;

        s->autoidle |= value & 3;

    /* Per-bank registers */

    case 0x84:	/* INTC_MIR */

        bank->mask = value;

        omap_inth_update(s, 0);

        omap_inth_update(s, 1);

    case 0x88:	/* INTC_MIR_CLEAR */

        bank->mask &= ~value;

        omap_inth_update(s, 0);

        omap_inth_update(s, 1);

    case 0x8c:	/* INTC_MIR_SET */

        bank->mask |= value;

    case 0x90:	/* INTC_ISR_SET */

        bank->irqs |= bank->swi |= value;

        omap_inth_update(s, 0);

        omap_inth_update(s, 1);

    case 0x94:	/* INTC_ISR_CLEAR */

        bank->swi &= ~value;

        bank->irqs = bank->swi & bank->inputs;

    /* Per-line registers */

    case 0x100 ... 0x300:	/* INTC_ILR */

        bank_no = (offset - 0x100) >> 7;

        if (bank_no > s->nbanks)

            break;

        bank = &s->bank[bank_no];

        line_no = (offset & 0x7f) >> 2;

        bank->priority[line_no] = (value >> 2) & 0x3f;

        bank->fiq &= ~(1 << line_no);

        bank->fiq |= (value & 1) << line_no;

    case 0x00:	/* INTC_REVISION */

    case 0x14:	/* INTC_SYSSTATUS */

    case 0x40:	/* INTC_SIR_IRQ */

    case 0x44:	/* INTC_SIR_FIQ */

    case 0x80:	/* INTC_ITR */

    case 0x98:	/* INTC_PENDING_IRQ */

    case 0x9c:	/* INTC_PENDING_FIQ */

        OMAP_RO_REG(addr);

    }

}


static int decode_hextile(VmncContext *c, uint8_t* dst, uint8_t* src, int w, int h, int stride)

{

    int i, j, k;

    int bg = 0, fg = 0, rects, color, flags, xy, wh;

    const int bpp = c->bpp2;

    uint8_t *dst2;

    int bw = 16, bh = 16;

    uint8_t *ssrc=src;

    for(j = 0; j < h; j += 16) {

        dst2 = dst;

        bw = 16;

        if(j + 16 > h) bh = h - j;

        for(i = 0; i < w; i += 16, dst2 += 16 * bpp) {

            if(i + 16 > w) bw = w - i;

            flags = *src++;

            if(flags & HT_RAW) {

                paint_raw(dst2, bw, bh, src, bpp, c->bigendian, stride);

                src += bw * bh * bpp;

            } else {

                if(flags & HT_BKG) {

                    bg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp;

                }

                if(flags & HT_FG) {

                    fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp;

                }

                rects = 0;

                if(flags & HT_SUB)

                    rects = *src++;

                color = (flags & HT_CLR);

                paint_rect(dst2, 0, 0, bw, bh, bg, bpp, stride);

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

                    if(color) {

                        fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp;

                    }

                    xy = *src++;

                    wh = *src++;

                    paint_rect(dst2, xy >> 4, xy & 0xF, (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride);

                }

            }

        }

        dst += stride * 16;

    }

    return src - ssrc;

}


static void filter_mb_mbaff_edgev( H264Context *h, uint8_t *pix, int stride, int16_t bS[4], int bsi, int qp ) {

    int i;

    int index_a = qp + h->slice_alpha_c0_offset;

    int alpha = (alpha_table+52)[index_a];

    int beta  = (beta_table+52)[qp + h->slice_beta_offset];

    for( i = 0; i < 8; i++, pix += stride) {

        const int bS_index = (i >> 1) * bsi;

        if( bS[bS_index] == 0 ) {

            continue;

        }

        if( bS[bS_index] < 4 ) {

            const int tc0 = (tc0_table+52)[index_a][bS[bS_index]];

            const int p0 = pix[-1];

            const int p1 = pix[-2];

            const int p2 = pix[-3];

            const int q0 = pix[0];

            const int q1 = pix[1];

            const int q2 = pix[2];

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

                FFABS( p1 - p0 ) < beta &&

                FFABS( q1 - q0 ) < beta ) {

                int tc = tc0;

                int i_delta;

                if( FFABS( p2 - p0 ) < beta ) {

                    if(tc0)

                    pix[-2] = p1 + av_clip( ( p2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( p1 << 1 ) ) >> 1, -tc0, tc0 );

                    tc++;

                }

                if( FFABS( q2 - q0 ) < beta ) {

                    if(tc0)

                    pix[1] = q1 + av_clip( ( q2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( q1 << 1 ) ) >> 1, -tc0, tc0 );

                    tc++;

                }

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

                pix[-1] = av_clip_uint8( p0 + i_delta );    /* p0' */

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

                tprintf(h->s.avctx, "filter_mb_mbaff_edgev i:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d\n# bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x]\n", i, qp[qp_index], index_a, alpha, beta, tc, bS[bS_index], pix[-3], p1, p0, q0, q1, pix[2], p1, pix[-1], pix[0], q1);

            }

        }else{

            const int p0 = pix[-1];

            const int p1 = pix[-2];

            const int p2 = pix[-3];

            const int q0 = pix[0];

            const int q1 = pix[1];

            const int q2 = pix[2];

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

                FFABS( p1 - p0 ) < beta &&

                FFABS( q1 - q0 ) < beta ) {

                if(FFABS( p0 - q0 ) < (( alpha >> 2 ) + 2 )){

                    if( FFABS( p2 - p0 ) < beta)

                    {

                        const int p3 = pix[-4];

                        /* p0', p1', p2' */

                        pix[-1] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;

                        pix[-2] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;

                        pix[-3] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;

                    } else {

                        /* p0' */

                        pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2;

                    }

                    if( FFABS( q2 - q0 ) < beta)

                    {

                        const int q3 = pix[3];

                        /* q0', q1', q2' */

                        pix[0] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;

                        pix[1] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;

                        pix[2] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;

                    } else {

                        /* q0' */

                        pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2;

                    }

                }else{

                    /* p0', q0' */

                    pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2;

                    pix[ 0] = ( 2*q1 + q0 + p1 + 2 ) >> 2;

                }

                tprintf(h->s.avctx, "filter_mb_mbaff_edgev i:%d, qp:%d, indexA:%d, alpha:%d, beta:%d\n# bS:4 -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x, %02x, %02x]\n", i, qp[qp_index], index_a, alpha, beta, p2, p1, p0, q0, q1, q2, pix[-3], pix[-2], pix[-1], pix[0], pix[1], pix[2]);

            }

        }

    }

}


static void arm_idct_add(UINT8 *dest, int line_size, DCTELEM *block)

{

    j_rev_dct_ARM (block);

    add_pixels_clamped(block, dest, line_size);

}


static inline void decode_block_intra(MadContext * t, DCTELEM * block)

{

    MpegEncContext *s = &t->s;

    int level, i, j, run;

    RLTable *rl = &ff_rl_mpeg1;

    const uint8_t *scantable = s->intra_scantable.permutated;

    int16_t *quant_matrix = s->intra_matrix;

    block[0] = (128 + get_sbits(&s->gb, 8)) * quant_matrix[0];

    /* The RL decoder is derived from mpeg1_decode_block_intra;

       Escaped level and run values a decoded differently */

    i = 0;

    {

        OPEN_READER(re, &s->gb);

        /* now quantify & encode AC coefficients */

        for (;;) {

            UPDATE_CACHE(re, &s->gb);

            GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);

            if (level == 127) {

                break;

            } else if (level != 0) {

                i += run;

                j = scantable[i];

                level = (level*quant_matrix[j]) >> 4;

                level = (level-1)|1;

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

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

            } else {

                /* escape */

                UPDATE_CACHE(re, &s->gb);

                level = SHOW_SBITS(re, &s->gb, 10); SKIP_BITS(re, &s->gb, 10);

                UPDATE_CACHE(re, &s->gb);

                run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);

                i += run;

                j = scantable[i];

                if (level < 0) {

                    level = -level;

                    level = (level*quant_matrix[j]) >> 4;

                    level = (level-1)|1;

                    level = -level;

                } else {

                    level = (level*quant_matrix[j]) >> 4;

                    level = (level-1)|1;

                }

            }

            if (i > 63) {

                av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);

                return;

            }

            block[j] = level;

        }

        CLOSE_READER(re, &s->gb);

    }

}


static void test_ivshmem_memdev(void)

{

    IVState state;

    /* just for the sake of checking memory-backend property */

    setup_vm_cmd(&state, "-object memory-backend-ram,size=1M,id=mb1"

                 " -device ivshmem,x-memdev=mb1", false);

    qtest_quit(state.qtest);

}


static av_cold void init_static(void)

{

    if (!huff_vlc[0].bits) {

    INIT_VLC_STATIC(&huff_vlc[0], VLC_BITS, 18,

                &ff_mlp_huffman_tables[0][0][1], 2, 1,

                &ff_mlp_huffman_tables[0][0][0], 2, 1, 512);

    INIT_VLC_STATIC(&huff_vlc[1], VLC_BITS, 16,

                &ff_mlp_huffman_tables[1][0][1], 2, 1,

                &ff_mlp_huffman_tables[1][0][0], 2, 1, 512);

    INIT_VLC_STATIC(&huff_vlc[2], VLC_BITS, 15,

                &ff_mlp_huffman_tables[2][0][1], 2, 1,

                &ff_mlp_huffman_tables[2][0][0], 2, 1, 512);

    ff_mlp_init_crc();


void gen_pc_load(CPUState *env, TranslationBlock *tb,

                unsigned long searched_pc, int pc_pos, void *puc)

{

    env->regs[15] = gen_opc_pc[pc_pos];

}


void virtio_scsi_dataplane_notify(VirtIODevice *vdev, VirtIOSCSIReq *req)

{

    if (virtio_should_notify(vdev, req->vq)) {

        event_notifier_set(virtio_queue_get_guest_notifier(req->vq));

    }

}


SwsFunc ff_yuv2rgb_init_mmx(SwsContext *c)

{

    int cpu_flags = av_get_cpu_flags();

    if (c->srcFormat != PIX_FMT_YUV420P &&

        c->srcFormat != PIX_FMT_YUVA420P)

        return NULL;

    if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2) {

        switch (c->dstFormat) {

        case PIX_FMT_RGB24:  return yuv420_rgb24_MMX2;

        case PIX_FMT_BGR24:  return yuv420_bgr24_MMX2;

        }

    }

    if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) {

        switch (c->dstFormat) {

            case PIX_FMT_RGB32:

                if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) {

#if HAVE_7REGS

                    return yuva420_rgb32_MMX;

#endif

                    break;

                } else return yuv420_rgb32_MMX;

            case PIX_FMT_BGR32:

                if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) {

#if HAVE_7REGS

                    return yuva420_bgr32_MMX;

#endif

                    break;

                } else return yuv420_bgr32_MMX;

            case PIX_FMT_RGB24:  return yuv420_rgb24_MMX;

            case PIX_FMT_BGR24:  return yuv420_bgr24_MMX;

            case PIX_FMT_RGB565: return yuv420_rgb16_MMX;

            case PIX_FMT_RGB555: return yuv420_rgb15_MMX;

        }

    }

    return NULL;

}


int ide_init_drive(IDEState *s, BlockDriverState *bs,

                   const char *version, const char *serial)

{

    int cylinders, heads, secs;

    uint64_t nb_sectors;

    s->bs = bs;

    bdrv_get_geometry(bs, &nb_sectors);

    bdrv_guess_geometry(bs, &cylinders, &heads, &secs);

    if (cylinders < 1 || cylinders > 16383) {

        error_report("cyls must be between 1 and 16383");

    if (heads < 1 || heads > 16) {

        error_report("heads must be between 1 and 16");

    if (secs < 1 || secs > 63) {

        error_report("secs must be between 1 and 63");

    s->cylinders = cylinders;

    s->heads = heads;

    s->sectors = secs;

    s->nb_sectors = nb_sectors;

    /* The SMART values should be preserved across power cycles

       but they aren't.  */

    s->smart_enabled = 1;

    s->smart_autosave = 1;

    s->smart_errors = 0;

    s->smart_selftest_count = 0;

    if (bdrv_get_type_hint(bs) == BDRV_TYPE_CDROM) {

        s->drive_kind = IDE_CD;

        bdrv_set_change_cb(bs, cdrom_change_cb, s);

    } else {

        if (bdrv_is_read_only(bs)) {

            error_report("Can't use a read-only drive");

    if (serial) {

        strncpy(s->drive_serial_str, serial, sizeof(s->drive_serial_str));

    } else {

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

                 "QM%05d", s->drive_serial);

    if (version) {

        pstrcpy(s->version, sizeof(s->version), version);

    } else {

        pstrcpy(s->version, sizeof(s->version), QEMU_VERSION);

    ide_reset(s);

    bdrv_set_removable(bs, s->drive_kind == IDE_CD);

    return 0;


SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,

                                      int unit, bool removable, int bootindex,

                                      const char *serial, Error **errp)

{

    const char *driver;

    DeviceState *dev;

    Error *err = NULL;

    driver = bdrv_is_sg(bdrv) ? "scsi-generic" : "scsi-disk";

    dev = qdev_create(&bus->qbus, driver);

    qdev_prop_set_uint32(dev, "scsi-id", unit);

    if (bootindex >= 0) {

        qdev_prop_set_int32(dev, "bootindex", bootindex);

    }

    if (object_property_find(OBJECT(dev), "removable", NULL)) {

        qdev_prop_set_bit(dev, "removable", removable);

    }

    if (serial) {

        qdev_prop_set_string(dev, "serial", serial);

    }

    if (qdev_prop_set_drive(dev, "drive", bdrv) < 0) {

        error_setg(errp, "Setting drive property failed");

        qdev_free(dev);

        return NULL;

    }

    object_property_set_bool(OBJECT(dev), true, "realized", &err);

    if (err != NULL) {

        error_propagate(errp, err);

        qdev_free(dev);

        return NULL;

    }

    return SCSI_DEVICE(dev);

}


static int unix_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)

{

    QEMUFileSocket *s = opaque;

    ssize_t len;

    for (;;) {

        len = read(s->fd, buf, size);

        if (len != -1) {

            break;

        }

        if (errno == EAGAIN) {

            yield_until_fd_readable(s->fd);

        } else if (errno != EINTR) {

            break;

        }

    }

    if (len == -1) {

        len = -errno;

    }

    return len;

}


DriveInfo *add_init_drive(const char *optstr)

{

    DriveInfo *dinfo;

    QemuOpts *opts;

    MachineClass *mc;

    opts = drive_def(optstr);

    if (!opts)

        return NULL;

    mc = MACHINE_GET_CLASS(current_machine);

    dinfo = drive_new(opts, mc->block_default_type);

    if (!dinfo) {

        qemu_opts_del(opts);

        return NULL;

    }

    return dinfo;

}


static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int log2w, int log2h, int stride){

    const int index= size2index[log2h][log2w];

    const int h= 1<<log2h;

    int code= get_vlc2(&f->gb, block_type_vlc[1-(f->version>1)][index].table, BLOCK_TYPE_VLC_BITS, 1);

    uint16_t *start= (uint16_t*)f->last_picture.data[0];

    uint16_t *end= start + stride*(f->avctx->height-h+1) - (1<<log2w);

    assert(code>=0 && code<=6);

    if(code == 0){

        src += f->mv[ *f->bytestream++ ];

        if(start > src || src > end){

            av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");

            return;

        }

        mcdc(dst, src, log2w, h, stride, 1, 0);

    }else if(code == 1){

        log2h--;

        decode_p_block(f, dst                  , src                  , log2w, log2h, stride);

        decode_p_block(f, dst + (stride<<log2h), src + (stride<<log2h), log2w, log2h, stride);

    }else if(code == 2){

        log2w--;

        decode_p_block(f, dst             , src             , log2w, log2h, stride);

        decode_p_block(f, dst + (1<<log2w), src + (1<<log2w), log2w, log2h, stride);

    }else if(code == 3 && f->version<2){

        mcdc(dst, src, log2w, h, stride, 1, 0);

    }else if(code == 4){

        src += f->mv[ *f->bytestream++ ];

        if(start > src || src > end){

            av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");

            return;

        }

        mcdc(dst, src, log2w, h, stride, 1, av_le2ne16(*f->wordstream++));

    }else if(code == 5){

        mcdc(dst, src, log2w, h, stride, 0, av_le2ne16(*f->wordstream++));

    }else if(code == 6){

        if(log2w){

            dst[0] = av_le2ne16(*f->wordstream++);

            dst[1] = av_le2ne16(*f->wordstream++);

        }else{

            dst[0     ] = av_le2ne16(*f->wordstream++);

            dst[stride] = av_le2ne16(*f->wordstream++);

        }

    }

}


static int mov_write_int8_metadata(AVFormatContext *s, AVIOContext *pb,

                                   const char *name, const char *tag,

                                   int len)

{

    AVDictionaryEntry *t = NULL;

    uint8_t num;

    if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))

        return 0;

    num = t ? atoi(t->value) : 0;

    avio_wb32(pb, len+8);

    ffio_wfourcc(pb, name);

    if (len==4) avio_wb32(pb, num);

    else        avio_w8 (pb, num);

    return len+8;

}


int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,

                     const uint8_t *buf, int len)

{

    unsigned int ssrc, h;

    int payload_type, seq, ret;

    AVStream *st;

    uint32_t timestamp;

    int rv= 0;

    if (!buf) {

        /* return the next packets, if any */

        if(s->st && s->parse_packet) {

            timestamp= 0; ///< Should not be used if buf is NULL, but should be set to the timestamp of the packet returned....

            rv= s->parse_packet(s, pkt, &timestamp, NULL, 0);

            finalize_packet(s, pkt, timestamp);

            return rv;

        } else {

            // TODO: Move to a dynamic packet handler (like above)

            if (s->read_buf_index >= s->read_buf_size)

                return -1;

            ret = mpegts_parse_packet(s->ts, pkt, s->buf + s->read_buf_index,

                                      s->read_buf_size - s->read_buf_index);

            if (ret < 0)

                return -1;

            s->read_buf_index += ret;

            if (s->read_buf_index < s->read_buf_size)

                return 1;

            else

                return 0;

        }

    }

    if (len < 12)

        return -1;

    if ((buf[0] & 0xc0) != (RTP_VERSION << 6))

        return -1;

    if (buf[1] >= 200 && buf[1] <= 204) {

        rtcp_parse_packet(s, buf, len);

        return -1;

    }

    payload_type = buf[1] & 0x7f;

    seq  = (buf[2] << 8) | buf[3];

    timestamp = decode_be32(buf + 4);

    ssrc = decode_be32(buf + 8);

    /* store the ssrc in the RTPDemuxContext */

    s->ssrc = ssrc;

    /* NOTE: we can handle only one payload type */

    if (s->payload_type != payload_type)

        return -1;

    st = s->st;

#if defined(DEBUG) || 1

    if (seq != ((s->seq + 1) & 0xffff)) {

        av_log(st?st->codec:NULL, AV_LOG_ERROR, "RTP: PT=%02x: bad cseq %04x expected=%04x\n",

               payload_type, seq, ((s->seq + 1) & 0xffff));

    }

#endif

    s->seq = seq;

    len -= 12;

    buf += 12;

    if (!st) {

        /* specific MPEG2TS demux support */

        ret = mpegts_parse_packet(s->ts, pkt, buf, len);

        if (ret < 0)

            return -1;

        if (ret < len) {

            s->read_buf_size = len - ret;

            memcpy(s->buf, buf + ret, s->read_buf_size);

            s->read_buf_index = 0;

            return 1;

        }

    } else {

        // at this point, the RTP header has been stripped;  This is ASSUMING that there is only 1 CSRC, which in't wise.

        switch(st->codec->codec_id) {

        case CODEC_ID_MP2:

            /* better than nothing: skip mpeg audio RTP header */

            if (len <= 4)

                return -1;

            h = decode_be32(buf);

            len -= 4;

            buf += 4;

            av_new_packet(pkt, len);

            memcpy(pkt->data, buf, len);

            break;

        case CODEC_ID_MPEG1VIDEO:

            /* better than nothing: skip mpeg video RTP header */

            if (len <= 4)

                return -1;

            h = decode_be32(buf);

            buf += 4;

            len -= 4;

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

                /* mpeg2 */

                if (len <= 4)

                    return -1;

                buf += 4;

                len -= 4;

            }

            av_new_packet(pkt, len);

            memcpy(pkt->data, buf, len);

            break;

            // moved from below, verbatim.  this is because this section handles packets, and the lower switch handles

            // timestamps.

            // TODO: Put this into a dynamic packet handler...

        case CODEC_ID_MPEG4AAC:

            if (rtp_parse_mp4_au(s, buf))

                return -1;

            {

                rtp_payload_data_t *infos = s->rtp_payload_data;

                if (infos == NULL)

                    return -1;

                buf += infos->au_headers_length_bytes + 2;

                len -= infos->au_headers_length_bytes + 2;

                /* XXX: Fixme we only handle the case where rtp_parse_mp4_au define

                    one au_header */

                av_new_packet(pkt, infos->au_headers[0].size);

                memcpy(pkt->data, buf, infos->au_headers[0].size);

                buf += infos->au_headers[0].size;

                len -= infos->au_headers[0].size;

            }

            s->read_buf_size = len;

            s->buf_ptr = buf;

            rv= 0;

            break;

        default:

            if(s->parse_packet) {

                rv= s->parse_packet(s, pkt, &timestamp, buf, len);

            } else {

                av_new_packet(pkt, len);

                memcpy(pkt->data, buf, len);

            }

            break;

        }

        // now perform timestamp things....

        finalize_packet(s, pkt, timestamp);

    }

    return rv;

}


static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,

                          IVITile *tile, AVCodecContext *avctx)

{

    int         x, y, mv_x, mv_y, mv_delta, offs, mb_offset, blks_per_mb,

                mv_scale, mb_type_bits, s;

    IVIMbInfo   *mb, *ref_mb;

    int         row_offset = band->mb_size * band->pitch;

    mb     = tile->mbs;

    ref_mb = tile->ref_mbs;

    offs   = tile->ypos * band->pitch + tile->xpos;

    blks_per_mb  = band->mb_size   != band->blk_size  ? 4 : 1;

    mb_type_bits = ctx->frame_type == FRAMETYPE_BIDIR ? 2 : 1;

    /* scale factor for motion vectors */

    mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3);

    mv_x = mv_y = 0;

    if (((tile->width + band->mb_size-1)/band->mb_size) * ((tile->height + band->mb_size-1)/band->mb_size) != tile->num_MBs) {

        av_log(avctx, AV_LOG_ERROR, "num_MBs mismatch %d %d %d %d\n", tile->width, tile->height, band->mb_size, tile->num_MBs);

        return -1;

    }

    for (y = tile->ypos; y < tile->ypos + tile->height; y += band->mb_size) {

        mb_offset = offs;

        for (x = tile->xpos; x < tile->xpos + tile->width; x += band->mb_size) {

            mb->xpos     = x;

            mb->ypos     = y;

            mb->buf_offs = mb_offset;

            if (get_bits1(&ctx->gb)) {

                if (ctx->frame_type == FRAMETYPE_INTRA) {

                    av_log(avctx, AV_LOG_ERROR, "Empty macroblock in an INTRA picture!\n");

                    return AVERROR_INVALIDDATA;

                }

                mb->type = 1; /* empty macroblocks are always INTER */

                mb->cbp  = 0; /* all blocks are empty */

                mb->q_delta = 0;

                if (!band->plane && !band->band_num && ctx->in_q) {

                    mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,

                                           IVI_VLC_BITS, 1);

                    mb->q_delta = IVI_TOSIGNED(mb->q_delta);

                }

                mb->mv_x = mb->mv_y = 0; /* no motion vector coded */

                if (band->inherit_mv) {

                    /* motion vector inheritance */

                    if (mv_scale) {

                        mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);

                        mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale);

                    } else {

                        mb->mv_x = ref_mb->mv_x;

                        mb->mv_y = ref_mb->mv_y;

                    }

                }

            } else {

                if (band->inherit_mv && ref_mb) {

                    mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */

                } else if (ctx->frame_type == FRAMETYPE_INTRA) {

                    mb->type = 0; /* mb_type is always INTRA for intra-frames */

                } else {

                    mb->type = get_bits(&ctx->gb, mb_type_bits);

                }

                mb->cbp = get_bits(&ctx->gb, blks_per_mb);

                mb->q_delta = 0;

                if (band->inherit_qdelta) {

                    if (ref_mb) mb->q_delta = ref_mb->q_delta;

                } else if (mb->cbp || (!band->plane && !band->band_num &&

                           ctx->in_q)) {

                    mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,

                                           IVI_VLC_BITS, 1);

                    mb->q_delta = IVI_TOSIGNED(mb->q_delta);

                }

                if (!mb->type) {

                    mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */

                } else {

                    if (band->inherit_mv) {

                        /* motion vector inheritance */

                        if (mv_scale) {

                            mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);

                            mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale);

                        } else {

                            mb->mv_x = ref_mb->mv_x;

                            mb->mv_y = ref_mb->mv_y;

                        }

                    } else {

                        /* decode motion vector deltas */

                        mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,

                                            IVI_VLC_BITS, 1);

                        mv_y += IVI_TOSIGNED(mv_delta);

                        mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,

                                            IVI_VLC_BITS, 1);

                        mv_x += IVI_TOSIGNED(mv_delta);

                        mb->mv_x = mv_x;

                        mb->mv_y = mv_y;

                    }

                }

            }

            s= band->is_halfpel;

            if (mb->type)

            if ( x +  (mb->mv_x   >>s) +                 (y+               (mb->mv_y   >>s))*band->pitch < 0 ||

                 x + ((mb->mv_x+s)>>s) + band->mb_size - 1

                   + (y+band->mb_size - 1 +((mb->mv_y+s)>>s))*band->pitch > band->bufsize -1) {

                av_log(avctx, AV_LOG_ERROR, "motion vector %d %d outside reference\n", x*s + mb->mv_x, y*s + mb->mv_y);

                return AVERROR_INVALIDDATA;

            }

            mb++;

            if (ref_mb)

                ref_mb++;

            mb_offset += band->mb_size;

        }

        offs += row_offset;

    }

    align_get_bits(&ctx->gb);

    return 0;

}


static int balloon_parse(const char *arg)

{

    QemuOpts *opts;

    if (strcmp(arg, "none") == 0) {

        return 0;

    }

    if (!strncmp(arg, "virtio", 6)) {

        if (arg[6] == ',') {

            /* have params -> parse them */

            opts = qemu_opts_parse(qemu_find_opts("device"), arg+7, 0);

            if (!opts)

                return  -1;

        } else {

            /* create empty opts */

            opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0);

        }

        qemu_opt_set(opts, "driver", "virtio-balloon");

        return 0;

    }

    return -1;

}


static inline void RENAME(yuv2yuvX)(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,

				    int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,

				    uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstW, int chrDstW)

{

#ifdef HAVE_MMX

	if(uDest != NULL)

	{

		asm volatile(

				YSCALEYUV2YV12X(0, CHR_MMX_FILTER_OFFSET)

				:: "r" (&c->redDither),

				"r" (uDest), "p" ((long)chrDstW)

				: "%"REG_a, "%"REG_d, "%"REG_S

			);

		asm volatile(

				YSCALEYUV2YV12X(4096, CHR_MMX_FILTER_OFFSET)

				:: "r" (&c->redDither),

				"r" (vDest), "p" ((long)chrDstW)

				: "%"REG_a, "%"REG_d, "%"REG_S

			);

	}

	asm volatile(

			YSCALEYUV2YV12X(0, LUM_MMX_FILTER_OFFSET)

			:: "r" (&c->redDither),

			   "r" (dest), "p" ((long)dstW)

			: "%"REG_a, "%"REG_d, "%"REG_S

		);

#else

#ifdef HAVE_ALTIVEC

yuv2yuvX_altivec_real(lumFilter, lumSrc, lumFilterSize,

		      chrFilter, chrSrc, chrFilterSize,

		      dest, uDest, vDest, dstW, chrDstW);

#else //HAVE_ALTIVEC

yuv2yuvXinC(lumFilter, lumSrc, lumFilterSize,

	    chrFilter, chrSrc, chrFilterSize,

	    dest, uDest, vDest, dstW, chrDstW);

#endif //!HAVE_ALTIVEC

#endif

}


int attribute_align_arg avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples,

                         int *frame_size_ptr,

                         uint8_t *buf, int buf_size)

{

    int ret;

    if((avctx->codec->capabilities & CODEC_CAP_DELAY) || buf_size){

        //FIXME remove the check below _after_ ensuring that all audio check that the available space is enough

        if(*frame_size_ptr < AVCODEC_MAX_AUDIO_FRAME_SIZE){

            av_log(avctx, AV_LOG_ERROR, "buffer smaller than AVCODEC_MAX_AUDIO_FRAME_SIZE\n");

            return -1;

        }

        if(*frame_size_ptr < FF_MIN_BUFFER_SIZE ||

        *frame_size_ptr < avctx->channels * avctx->frame_size * sizeof(int16_t) ||

        *frame_size_ptr < buf_size){

            av_log(avctx, AV_LOG_ERROR, "buffer %d too small\n", *frame_size_ptr);

            return -1;

        }

        ret = avctx->codec->decode(avctx, samples, frame_size_ptr,

                                buf, buf_size);

        avctx->frame_number++;

    }else{

        ret= 0;

        *frame_size_ptr=0;

    }

    return ret;

}


static void nbd_co_receive_reply(NBDClientSession *s,

                                 NBDRequest *request,

                                 NBDReply *reply,

                                 QEMUIOVector *qiov)

{

    int ret;

    /* Wait until we're woken up by nbd_read_reply_entry.  */

    qemu_coroutine_yield();

    *reply = s->reply;

    if (reply->handle != request->handle ||

        !s->ioc) {

        reply->error = EIO;

    } else {

        if (qiov && reply->error == 0) {

            ret = nbd_rwv(s->ioc, qiov->iov, qiov->niov, request->len, true,

                          NULL);

            if (ret != request->len) {

                reply->error = EIO;

            }

        }

        /* Tell the read handler to read another header.  */

        s->reply.handle = 0;

    }

}


static const char *local_mapped_attr_path(FsContext *ctx,

                                          const char *path, char *buffer)

{

    char *dir_name;

    char *tmp_path = strdup(path);

    char *base_name = basename(tmp_path);

    /* NULL terminate the directory */

    dir_name = tmp_path;

    *(base_name - 1) = '\0';

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

             ctx->fs_root, dir_name, VIRTFS_META_DIR, base_name);

    free(tmp_path);

    return buffer;

}


void usb_host_info(Monitor *mon, const QDict *qdict)

{

    libusb_device **devs;

    struct libusb_device_descriptor ddesc;

    char port[16];

    int i, n;

    if (usb_host_init() != 0) {

        return;

    }

    n = libusb_get_device_list(ctx, &devs);

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

        if (libusb_get_device_descriptor(devs[i], &ddesc) != 0) {

            continue;

        }

        if (ddesc.bDeviceClass == LIBUSB_CLASS_HUB) {

            continue;

        }

        usb_host_get_port(devs[i], port, sizeof(port));

        monitor_printf(mon, "  Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",

                       libusb_get_bus_number(devs[i]),

                       libusb_get_device_address(devs[i]),

                       port,

                       speed_name[libusb_get_device_speed(devs[i])]);

        monitor_printf(mon, "    Class %02x:", ddesc.bDeviceClass);

        monitor_printf(mon, " USB device %04x:%04x",

                       ddesc.idVendor, ddesc.idProduct);

        if (ddesc.iProduct) {

            libusb_device_handle *handle;

            if (libusb_open(devs[i], &handle) == 0) {

                unsigned char name[64] = "";

                libusb_get_string_descriptor_ascii(handle,

                                                   ddesc.iProduct,

                                                   name, sizeof(name));

                libusb_close(handle);

                monitor_printf(mon, ", %s", name);

            }

        }

        monitor_printf(mon, "\n");

    }

    libusb_free_device_list(devs, 1);

}


static void gen_mulldo(DisasContext *ctx)

{

    TCGv_i64 t0 = tcg_temp_new_i64();

    TCGv_i64 t1 = tcg_temp_new_i64();

    tcg_gen_muls2_i64(t0, t1, cpu_gpr[rA(ctx->opcode)],

                      cpu_gpr[rB(ctx->opcode)]);

    tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], t0);

    tcg_gen_sari_i64(t0, t0, 63);

    tcg_gen_setcond_i64(TCG_COND_NE, cpu_ov, t0, t1);

    tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);

    tcg_temp_free_i64(t0);

    tcg_temp_free_i64(t1);

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

        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);


static inline target_phys_addr_t get_pgaddr (target_phys_addr_t sdr1,

                                             int sdr_sh,

                                             target_phys_addr_t hash,

                                             target_phys_addr_t mask)

{

    return (sdr1 & ((target_ulong)(-1ULL) << sdr_sh)) | (hash & mask);

}


static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize)

{

    unsigned char *destptr_bak = destptr;

    unsigned char *destptr_end = destptr + destsize;

    const unsigned char *srcptr_end = srcptr + srclen;

    unsigned mask = *srcptr++;

    unsigned maskbit = 0x80;

    while (srcptr < srcptr_end && destptr < destptr_end) {

        if (!(mask & maskbit)) {

            memcpy(destptr, srcptr, 4);

            destptr += 4;

            srcptr += 4;

        } else {

            unsigned ofs = bytestream_get_le16(&srcptr);

            unsigned cnt = (ofs >> 11) + 1;

            ofs &= 0x7ff;

            ofs = FFMIN(ofs, destptr - destptr_bak);

            cnt *= 4;

            cnt = FFMIN(cnt, destptr_end - destptr);

            av_memcpy_backptr(destptr, ofs, cnt);

            destptr += cnt;

        }

        maskbit >>= 1;

        if (!maskbit) {

            mask = *srcptr++;

            while (!mask) {

                if (destptr_end - destptr < 32 || srcptr_end - srcptr < 32) break;

                memcpy(destptr, srcptr, 32);

                destptr += 32;

                srcptr += 32;

                mask = *srcptr++;

            }

            maskbit = 0x80;

        }

    }

    return destptr - destptr_bak;

}


static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)

{

#ifdef DEBUG_UNASSIGNED

    printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);

#endif

#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)

    do_unassigned_access(addr, 0, 0, 0, 1);

#endif

    return 0;

}


static int mxg_update_cache(AVFormatContext *s, unsigned int cache_size)

{

    MXGContext *mxg = s->priv_data;

    unsigned int current_pos = mxg->buffer_ptr - mxg->buffer;

    unsigned int soi_pos;

    int ret;

    /* reallocate internal buffer */

    if (current_pos > current_pos + cache_size)

        return AVERROR(ENOMEM);

    soi_pos = mxg->soi_ptr - mxg->buffer;

    mxg->buffer = av_fast_realloc(mxg->buffer, &mxg->buffer_size,

                                  current_pos + cache_size +

                                  FF_INPUT_BUFFER_PADDING_SIZE);

    if (!mxg->buffer)

        return AVERROR(ENOMEM);

    mxg->buffer_ptr = mxg->buffer + current_pos;

    if (mxg->soi_ptr) mxg->soi_ptr = mxg->buffer + soi_pos;

    /* get data */

    ret = avio_read(s->pb, mxg->buffer_ptr + mxg->cache_size,

                     cache_size - mxg->cache_size);

    if (ret < 0)

        return ret;

    mxg->cache_size += ret;

    return ret;

}


vubr_set_mem_table_exec(VubrDev *dev, VhostUserMsg *vmsg)

{

    int i;

    VhostUserMemory *memory = &vmsg->payload.memory;

    dev->nregions = memory->nregions;

    DPRINT("Nregions: %d\n", memory->nregions);

    for (i = 0; i < dev->nregions; i++) {

        void *mmap_addr;

        VhostUserMemoryRegion *msg_region = &memory->regions[i];

        VubrDevRegion *dev_region = &dev->regions[i];

        DPRINT("Region %d\n", i);

        DPRINT("    guest_phys_addr: 0x%016"PRIx64"\n",

               msg_region->guest_phys_addr);

        DPRINT("    memory_size:     0x%016"PRIx64"\n",

               msg_region->memory_size);

        DPRINT("    userspace_addr   0x%016"PRIx64"\n",

               msg_region->userspace_addr);

        DPRINT("    mmap_offset      0x%016"PRIx64"\n",

               msg_region->mmap_offset);

        dev_region->gpa = msg_region->guest_phys_addr;

        dev_region->size = msg_region->memory_size;

        dev_region->qva = msg_region->userspace_addr;

        dev_region->mmap_offset = msg_region->mmap_offset;

        /* We don't use offset argument of mmap() since the

         * mapped address has to be page aligned, and we use huge

         * pages.  */

        mmap_addr = mmap(0, dev_region->size + dev_region->mmap_offset,

                         PROT_READ | PROT_WRITE, MAP_SHARED,

                         vmsg->fds[i], 0);

        if (mmap_addr == MAP_FAILED) {

            vubr_die("mmap");

        }

        dev_region->mmap_addr = (uint64_t) mmap_addr;

        DPRINT("    mmap_addr:       0x%016"PRIx64"\n", dev_region->mmap_addr);

    }

    return 0;

}


static av_cold int dilate_init(AVFilterContext *ctx, const char *args)

{

    OCVContext *s = ctx->priv;

    DilateContext *dilate = s->priv;

    char default_kernel_str[] = "3x3+0x0/rect";

    char *kernel_str;

    const char *buf = args;

    int ret;

    dilate->nb_iterations = 1;

    if (args)

        kernel_str = av_get_token(&buf, "|");

    if ((ret = parse_iplconvkernel(&dilate->kernel,

                                   *kernel_str ? kernel_str : default_kernel_str,

                                   ctx)) < 0)

        return ret;

    av_free(kernel_str);

    sscanf(buf, "|%d", &dilate->nb_iterations);

    av_log(ctx, AV_LOG_VERBOSE, "iterations_nb:%d\n", dilate->nb_iterations);

    if (dilate->nb_iterations <= 0) {

        av_log(ctx, AV_LOG_ERROR, "Invalid non-positive value '%d' for nb_iterations\n",

               dilate->nb_iterations);

        return AVERROR(EINVAL);

    }

    return 0;

}


static int transcode(OutputFile *output_files,

                     int nb_output_files,

                     InputFile *input_files,

                     int nb_input_files)

{

    int ret = 0, i;

    AVFormatContext *is, *os;

    AVCodecContext *codec, *icodec;

    OutputStream *ost;

    InputStream *ist;

    char error[1024];

    int key;

    int want_sdp = 1;

    uint8_t *no_packet;

    int no_packet_count=0;

    int64_t timer_start;

    if (!(no_packet = av_mallocz(nb_input_files)))

        exit_program(1);

    if (rate_emu)

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

            input_streams[i].start = av_gettime();

    /* output stream init */

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

        os = output_files[i].ctx;

        if (!os->nb_streams && !(os->oformat->flags & AVFMT_NOSTREAMS)) {

            av_dump_format(os, i, os->filename, 1);

            fprintf(stderr, "Output file #%d does not contain any stream\n", i);

            ret = AVERROR(EINVAL);

            goto fail;

        }

    }

    /* for each output stream, we compute the right encoding parameters */

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

        ost = &output_streams[i];

        os = output_files[ost->file_index].ctx;

        ist = &input_streams[ost->source_index];

        codec = ost->st->codec;

        icodec = ist->st->codec;

        ost->st->disposition = ist->st->disposition;

        codec->bits_per_raw_sample= icodec->bits_per_raw_sample;

        codec->chroma_sample_location = icodec->chroma_sample_location;

        if (ost->st->stream_copy) {

            uint64_t extra_size = (uint64_t)icodec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE;

            if (extra_size > INT_MAX) {

                ret = AVERROR(EINVAL);

                goto fail;

            }

            /* if stream_copy is selected, no need to decode or encode */

            codec->codec_id = icodec->codec_id;

            codec->codec_type = icodec->codec_type;

            if(!codec->codec_tag){

                if(   !os->oformat->codec_tag

                   || av_codec_get_id (os->oformat->codec_tag, icodec->codec_tag) == codec->codec_id

                   || av_codec_get_tag(os->oformat->codec_tag, icodec->codec_id) <= 0)

                    codec->codec_tag = icodec->codec_tag;

            }

            codec->bit_rate = icodec->bit_rate;

            codec->rc_max_rate    = icodec->rc_max_rate;

            codec->rc_buffer_size = icodec->rc_buffer_size;

            codec->extradata= av_mallocz(extra_size);

            if (!codec->extradata) {

                ret = AVERROR(ENOMEM);

                goto fail;

            }

            memcpy(codec->extradata, icodec->extradata, icodec->extradata_size);

            codec->extradata_size= icodec->extradata_size;

            codec->time_base = ist->st->time_base;

            if(!strcmp(os->oformat->name, "avi")) {

                if(!copy_tb && av_q2d(icodec->time_base)*icodec->ticks_per_frame > 2*av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/500){

                    codec->time_base = icodec->time_base;

                    codec->time_base.num *= icodec->ticks_per_frame;

                    codec->time_base.den *= 2;

                }

            } else if(!(os->oformat->flags & AVFMT_VARIABLE_FPS)) {

                if(!copy_tb && av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/500){

                    codec->time_base = icodec->time_base;

                    codec->time_base.num *= icodec->ticks_per_frame;

                }

            }

            av_reduce(&codec->time_base.num, &codec->time_base.den,

                        codec->time_base.num, codec->time_base.den, INT_MAX);

            switch(codec->codec_type) {

            case AVMEDIA_TYPE_AUDIO:

                if(audio_volume != 256) {

                    fprintf(stderr,"-acodec copy and -vol are incompatible (frames are not decoded)\n");

                    exit_program(1);

                }

                codec->channel_layout = icodec->channel_layout;

                codec->sample_rate = icodec->sample_rate;

                codec->channels = icodec->channels;

                codec->frame_size = icodec->frame_size;

                codec->audio_service_type = icodec->audio_service_type;

                codec->block_align= icodec->block_align;

                if(codec->block_align == 1 && codec->codec_id == CODEC_ID_MP3)

                    codec->block_align= 0;

                if(codec->codec_id == CODEC_ID_AC3)

                    codec->block_align= 0;

                break;

            case AVMEDIA_TYPE_VIDEO:

                codec->pix_fmt = icodec->pix_fmt;

                codec->width = icodec->width;

                codec->height = icodec->height;

                codec->has_b_frames = icodec->has_b_frames;

                if (!codec->sample_aspect_ratio.num) {

                    codec->sample_aspect_ratio =

                    ost->st->sample_aspect_ratio =

                        ist->st->sample_aspect_ratio.num ? ist->st->sample_aspect_ratio :

                        ist->st->codec->sample_aspect_ratio.num ?

                        ist->st->codec->sample_aspect_ratio : (AVRational){0, 1};

                }

                break;

            case AVMEDIA_TYPE_SUBTITLE:

                codec->width = icodec->width;

                codec->height = icodec->height;

                break;

            case AVMEDIA_TYPE_DATA:

                break;

            default:

                abort();

            }

        } else {

            if (!ost->enc)

                ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);

            switch(codec->codec_type) {

            case AVMEDIA_TYPE_AUDIO:

                ost->fifo= av_fifo_alloc(1024);

                if (!ost->fifo) {

                    ret = AVERROR(ENOMEM);

                    goto fail;

                }

                ost->reformat_pair = MAKE_SFMT_PAIR(AV_SAMPLE_FMT_NONE,AV_SAMPLE_FMT_NONE);

                if (!codec->sample_rate) {

                    codec->sample_rate = icodec->sample_rate;

                }

                choose_sample_rate(ost->st, ost->enc);

                codec->time_base = (AVRational){1, codec->sample_rate};

                if (codec->sample_fmt == AV_SAMPLE_FMT_NONE)

                    codec->sample_fmt = icodec->sample_fmt;

                choose_sample_fmt(ost->st, ost->enc);

                if (!codec->channels) {

                    codec->channels = icodec->channels;

                    codec->channel_layout = icodec->channel_layout;

                }

                if (av_get_channel_layout_nb_channels(codec->channel_layout) != codec->channels)

                    codec->channel_layout = 0;

                ost->audio_resample = codec->sample_rate != icodec->sample_rate || audio_sync_method > 1;

                icodec->request_channels = codec->channels;

                ist->decoding_needed = 1;

                ost->encoding_needed = 1;

                ost->resample_sample_fmt  = icodec->sample_fmt;

                ost->resample_sample_rate = icodec->sample_rate;

                ost->resample_channels    = icodec->channels;

                break;

            case AVMEDIA_TYPE_VIDEO:

                if (codec->pix_fmt == PIX_FMT_NONE)

                    codec->pix_fmt = icodec->pix_fmt;

                choose_pixel_fmt(ost->st, ost->enc);

                if (ost->st->codec->pix_fmt == PIX_FMT_NONE) {

                    fprintf(stderr, "Video pixel format is unknown, stream cannot be encoded\n");

                    exit_program(1);

                }

                if (!codec->width || !codec->height) {

                    codec->width  = icodec->width;

                    codec->height = icodec->height;

                }

                ost->video_resample = codec->width   != icodec->width  ||

                                      codec->height  != icodec->height ||

                                      codec->pix_fmt != icodec->pix_fmt;

                if (ost->video_resample) {

                    codec->bits_per_raw_sample= frame_bits_per_raw_sample;

                }

                ost->resample_height = icodec->height;

                ost->resample_width  = icodec->width;

                ost->resample_pix_fmt= icodec->pix_fmt;

                ost->encoding_needed = 1;

                ist->decoding_needed = 1;

                if (!ost->frame_rate.num)

                    ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25,1};

                if (ost->enc && ost->enc->supported_framerates && !force_fps) {

                    int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates);

                    ost->frame_rate = ost->enc->supported_framerates[idx];

                }

                codec->time_base = (AVRational){ost->frame_rate.den, ost->frame_rate.num};

                if(   av_q2d(codec->time_base) < 0.001 && video_sync_method

                   && (video_sync_method==1 || (video_sync_method<0 && !(os->oformat->flags & AVFMT_VARIABLE_FPS)))){

                    av_log(os, AV_LOG_WARNING, "Frame rate very high for a muxer not effciciently supporting it.\n"

                                               "Please consider specifiying a lower framerate, a different muxer or -vsync 2\n");

                }

#if CONFIG_AVFILTER

                if (configure_video_filters(ist, ost)) {

                    fprintf(stderr, "Error opening filters!\n");

                    exit(1);

                }

#endif

                break;

            case AVMEDIA_TYPE_SUBTITLE:

                ost->encoding_needed = 1;

                ist->decoding_needed = 1;

                break;

            default:

                abort();

                break;

            }

            /* two pass mode */

            if (ost->encoding_needed && codec->codec_id != CODEC_ID_H264 &&

                (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) {

                char logfilename[1024];

                FILE *f;

                snprintf(logfilename, sizeof(logfilename), "%s-%d.log",

                         pass_logfilename_prefix ? pass_logfilename_prefix : DEFAULT_PASS_LOGFILENAME_PREFIX,

                         i);

                if (codec->flags & CODEC_FLAG_PASS1) {

                    f = fopen(logfilename, "wb");

                    if (!f) {

                        fprintf(stderr, "Cannot write log file '%s' for pass-1 encoding: %s\n", logfilename, strerror(errno));

                        exit_program(1);

                    }

                    ost->logfile = f;

                } else {

                    char  *logbuffer;

                    size_t logbuffer_size;

                    if (read_file(logfilename, &logbuffer, &logbuffer_size) < 0) {

                        fprintf(stderr, "Error reading log file '%s' for pass-2 encoding\n", logfilename);

                        exit_program(1);

                    }

                    codec->stats_in = logbuffer;

                }

            }

        }

        if(codec->codec_type == AVMEDIA_TYPE_VIDEO){

            /* maximum video buffer size is 6-bytes per pixel, plus DPX header size */

            int size= codec->width * codec->height;

            bit_buffer_size= FFMAX(bit_buffer_size, 6*size + 1664);

        }

    }

    if (!bit_buffer)

        bit_buffer = av_malloc(bit_buffer_size);

    if (!bit_buffer) {

        fprintf(stderr, "Cannot allocate %d bytes output buffer\n",

                bit_buffer_size);

        ret = AVERROR(ENOMEM);

        goto fail;

    }

    /* open each encoder */

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

        ost = &output_streams[i];

        if (ost->encoding_needed) {

            AVCodec *codec = ost->enc;

            AVCodecContext *dec = input_streams[ost->source_index].st->codec;

            if (!codec) {

                snprintf(error, sizeof(error), "Encoder (codec %s) not found for output stream #%d.%d",

                         avcodec_get_name(ost->st->codec->codec_id), ost->file_index, ost->index);

                ret = AVERROR(EINVAL);

                goto dump_format;

            }

            if (dec->subtitle_header) {

                ost->st->codec->subtitle_header = av_malloc(dec->subtitle_header_size);

                if (!ost->st->codec->subtitle_header) {

                    ret = AVERROR(ENOMEM);

                    goto dump_format;

                }

                memcpy(ost->st->codec->subtitle_header, dec->subtitle_header, dec->subtitle_header_size);

                ost->st->codec->subtitle_header_size = dec->subtitle_header_size;

            }

            if (avcodec_open2(ost->st->codec, codec, &ost->opts) < 0) {

                snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height",

                        ost->file_index, ost->index);

                ret = AVERROR(EINVAL);

                goto dump_format;

            }

            assert_codec_experimental(ost->st->codec, 1);

            assert_avoptions(ost->opts);

            if (ost->st->codec->bit_rate && ost->st->codec->bit_rate < 1000)

                av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."

                                             "It takes bits/s as argument, not kbits/s\n");

            extra_size += ost->st->codec->extradata_size;

        }

    }

    /* init input streams */

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

        if ((ret = init_input_stream(i, output_streams, nb_output_streams, error, sizeof(error)) < 0))

            goto dump_format;

    /* open files and write file headers */

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

        os = output_files[i].ctx;

        if (avformat_write_header(os, &output_files[i].opts) < 0) {

            snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i);

            ret = AVERROR(EINVAL);

            goto dump_format;

        }

//        assert_avoptions(output_files[i].opts);

        if (strcmp(os->oformat->name, "rtp")) {

            want_sdp = 0;

        }

    }

 dump_format:

    /* dump the file output parameters - cannot be done before in case

       of stream copy */

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

        av_dump_format(output_files[i].ctx, i, output_files[i].ctx->filename, 1);

    }

    /* dump the stream mapping */

    if (verbose >= 0) {

        fprintf(stderr, "Stream mapping:\n");

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

            ost = &output_streams[i];

            fprintf(stderr, "  Stream #%d.%d -> #%d.%d",

                    input_streams[ost->source_index].file_index,

                    input_streams[ost->source_index].st->index,

                    ost->file_index,

                    ost->index);

            if (ost->sync_ist != &input_streams[ost->source_index])

                fprintf(stderr, " [sync #%d.%d]",

                        ost->sync_ist->file_index,

                        ost->sync_ist->st->index);

            if(ost->encoding_needed)

                fprintf(stderr, ": %s -> %s",

                    input_streams[ost->source_index].dec ?

                        input_streams[ost->source_index].dec->name : "?",

                    ost->enc ? ost->enc->name : "?");

            else

                fprintf(stderr, ": copy");

            fprintf(stderr, "\n");

        }

    }

    if (ret) {

        fprintf(stderr, "%s\n", error);

        goto fail;

    }

    if (want_sdp) {

        print_sdp(output_files, nb_output_files);

    }

    if (!using_stdin) {

        if(verbose >= 0)

            fprintf(stderr, "Press [q] to stop, [?] for help\n");

        avio_set_interrupt_cb(decode_interrupt_cb);

    }

    term_init();

    timer_start = av_gettime();

    for(; received_sigterm == 0;) {

        int file_index, ist_index;

        AVPacket pkt;

        int64_t ipts_min;

        double opts_min;

    redo:

        ipts_min= INT64_MAX;

        opts_min= 1e100;

        /* if 'q' pressed, exits */

        if (!using_stdin) {

            if (q_pressed)

                break;

            /* read_key() returns 0 on EOF */

            key = read_key();

            if (key == 'q')

                break;

            if (key == '+') verbose++;

            if (key == '-') verbose--;

            if (key == 's') qp_hist     ^= 1;

            if (key == 'h'){

                if (do_hex_dump){

                    do_hex_dump = do_pkt_dump = 0;

                } else if(do_pkt_dump){

                    do_hex_dump = 1;

                } else

                    do_pkt_dump = 1;

                av_log_set_level(AV_LOG_DEBUG);

            }

            if (key == 'c' || key == 'C'){

                char ret[4096], target[64], cmd[256], arg[256]={0};

                double ts;

                fprintf(stderr, "\nEnter command: <target> <time> <command>[ <argument>]\n");

                if(scanf("%4095[^\n\r]%*c", ret) == 1 && sscanf(ret, "%63[^ ] %lf %255[^ ] %255[^\n]", target, &ts, cmd, arg) >= 3){

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

                        int r;

                        ost = &output_streams[i];

                        if(ost->graph){

                            if(ts<0){

                                r= avfilter_graph_send_command(ost->graph, target, cmd, arg, ret, sizeof(ret), key == 'c' ? AVFILTER_CMD_FLAG_ONE : 0);

                                fprintf(stderr, "Command reply for %d: %d, %s\n", i, r, ret);

                            }else{

                                r= avfilter_graph_queue_command(ost->graph, target, cmd, arg, 0, ts);

                            }

                        }

                    }

                }else{

                    fprintf(stderr, "Parse error\n");

                }

            }

            if (key == 'd' || key == 'D'){

                int debug=0;

                if(key == 'D') {

                    debug = input_streams[0].st->codec->debug<<1;

                    if(!debug) debug = 1;

                    while(debug & (FF_DEBUG_DCT_COEFF|FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) //unsupported, would just crash

                        debug += debug;

                }else

                    scanf("%d", &debug);

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

                    input_streams[i].st->codec->debug = debug;

                }

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

                    ost = &output_streams[i];

                    ost->st->codec->debug = debug;

                }

                if(debug) av_log_set_level(AV_LOG_DEBUG);

                fprintf(stderr,"debug=%d\n", debug);

            }

            if (key == '?'){

                fprintf(stderr, "key    function\n"

                                "?      show this help\n"

                                "+      increase verbosity\n"

                                "-      decrease verbosity\n"

                                "c      Send command to filtergraph\n"

                                "D      cycle through available debug modes\n"

                                "h      dump packets/hex press to cycle through the 3 states\n"

                                "q      quit\n"

                                "s      Show QP histogram\n"

                );

            }

        }

        /* select the stream that we must read now by looking at the

           smallest output pts */

        file_index = -1;

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

            OutputFile *of;

            int64_t ipts;

            double  opts;

            ost = &output_streams[i];

            of = &output_files[ost->file_index];

            os = output_files[ost->file_index].ctx;

            ist = &input_streams[ost->source_index];

            if (ost->is_past_recording_time || no_packet[ist->file_index] ||

                (os->pb && avio_tell(os->pb) >= of->limit_filesize))

                continue;

            opts = ost->st->pts.val * av_q2d(ost->st->time_base);

            ipts = ist->pts;

            if (!input_files[ist->file_index].eof_reached){

                if(ipts < ipts_min) {

                    ipts_min = ipts;

                    if(input_sync ) file_index = ist->file_index;

                }

                if(opts < opts_min) {

                    opts_min = opts;

                    if(!input_sync) file_index = ist->file_index;

                }

            }

            if(ost->frame_number >= max_frames[ost->st->codec->codec_type]){

                file_index= -1;

                break;

            }

        }

        /* if none, if is finished */

        if (file_index < 0) {

            if(no_packet_count){

                no_packet_count=0;

                memset(no_packet, 0, nb_input_files);

                usleep(10000);

                continue;

            }

            break;

        }

        /* read a frame from it and output it in the fifo */

        is = input_files[file_index].ctx;

        ret= av_read_frame(is, &pkt);

        if(ret == AVERROR(EAGAIN)){

            no_packet[file_index]=1;

            no_packet_count++;

            continue;

        }

        if (ret < 0) {

            input_files[file_index].eof_reached = 1;

            if (opt_shortest)

                break;

            else

                continue;

        }

        no_packet_count=0;

        memset(no_packet, 0, nb_input_files);

        if (do_pkt_dump) {

            av_pkt_dump_log2(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump,

                             is->streams[pkt.stream_index]);

        }

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

           dynamically in stream : we ignore them */

        if (pkt.stream_index >= input_files[file_index].nb_streams)

            goto discard_packet;

        ist_index = input_files[file_index].ist_index + pkt.stream_index;

        ist = &input_streams[ist_index];

        if (ist->discard)

            goto discard_packet;

        if (pkt.dts != AV_NOPTS_VALUE)

            pkt.dts += av_rescale_q(input_files[ist->file_index].ts_offset, AV_TIME_BASE_Q, ist->st->time_base);

        if (pkt.pts != AV_NOPTS_VALUE)

            pkt.pts += av_rescale_q(input_files[ist->file_index].ts_offset, AV_TIME_BASE_Q, ist->st->time_base);

        if (ist->ts_scale) {

            if(pkt.pts != AV_NOPTS_VALUE)

                pkt.pts *= ist->ts_scale;

            if(pkt.dts != AV_NOPTS_VALUE)

                pkt.dts *= ist->ts_scale;

        }

//        fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %d\n", ist->next_pts, pkt.dts, input_files[ist->file_index].ts_offset, ist->st->codec->codec_type);

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

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

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

            int64_t delta= pkt_dts - ist->next_pts;

            if((delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||

                (delta > 1LL*dts_delta_threshold*AV_TIME_BASE &&

                 ist->st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) ||

                pkt_dts+1<ist->pts)&& !copy_ts){

                input_files[ist->file_index].ts_offset -= delta;

                if (verbose > 2)

                    fprintf(stderr, "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",

                            delta, input_files[ist->file_index].ts_offset);

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

                if(pkt.pts != AV_NOPTS_VALUE)

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

            }

        }

        //fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->st->index, pkt.size);

        if (output_packet(ist, ist_index, output_streams, nb_output_streams, &pkt) < 0) {

            if (verbose >= 0)

                fprintf(stderr, "Error while decoding stream #%d.%d\n",

                        ist->file_index, ist->st->index);

            if (exit_on_error)

                exit_program(1);

            av_free_packet(&pkt);

            goto redo;

        }

    discard_packet:

        av_free_packet(&pkt);

        /* dump report by using the output first video and audio streams */

        print_report(output_files, output_streams, nb_output_streams, 0, timer_start);

    }

    /* at the end of stream, we must flush the decoder buffers */

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

        ist = &input_streams[i];

        if (ist->decoding_needed) {

            output_packet(ist, i, output_streams, nb_output_streams, NULL);

        }

    }

    flush_encoders(output_streams, nb_output_streams);

    term_exit();

    /* write the trailer if needed and close file */

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

        os = output_files[i].ctx;

        av_write_trailer(os);

    }

    /* dump report by using the first video and audio streams */

    print_report(output_files, output_streams, nb_output_streams, 1, timer_start);

    /* close each encoder */

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

        ost = &output_streams[i];

        if (ost->encoding_needed) {

            av_freep(&ost->st->codec->stats_in);

            avcodec_close(ost->st->codec);

        }

#if CONFIG_AVFILTER

        avfilter_graph_free(&ost->graph);

#endif

    }

    /* close each decoder */

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

        ist = &input_streams[i];

        if (ist->decoding_needed) {

            avcodec_close(ist->st->codec);

        }

    }

    /* finished ! */

    ret = 0;

 fail:

    av_freep(&bit_buffer);

    av_freep(&no_packet);

    if (output_streams) {

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

            ost = &output_streams[i];

            if (ost) {

                if (ost->st->stream_copy)

                    av_freep(&ost->st->codec->extradata);

                if (ost->logfile) {

                    fclose(ost->logfile);

                    ost->logfile = NULL;

                }

                av_fifo_free(ost->fifo); /* works even if fifo is not

                                             initialized but set to zero */

                av_freep(&ost->st->codec->subtitle_header);

                av_free(ost->resample_frame.data[0]);

                av_free(ost->forced_kf_pts);

                if (ost->video_resample)

                    sws_freeContext(ost->img_resample_ctx);

                if (ost->resample)

                    audio_resample_close(ost->resample);

                if (ost->reformat_ctx)

                    av_audio_convert_free(ost->reformat_ctx);

                av_dict_free(&ost->opts);

            }

        }

    }

    return ret;

}


static int dvvideo_decode_frame(AVCodecContext *avctx,

                                 void *data, int *data_size,

                                 uint8_t *buf, int buf_size)

{

    DVVideoContext *s = avctx->priv_data;

    /* special case for last picture */

    if(buf_size==0)

        return 0;

    s->sys = dv_frame_profile(buf);

    if (!s->sys || buf_size < s->sys->frame_size)

        return -1; /* NOTE: we only accept several full frames */

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

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

    s->picture.reference = 0;

    avctx->pix_fmt = s->sys->pix_fmt;

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

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

    if(avctx->get_buffer(avctx, &s->picture) < 0) {

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

        return -1;

    }

    s->picture.interlaced_frame = 1;

    s->picture.top_field_first = 0;

    s->buf = buf;

    avctx->execute(avctx, dv_decode_mt, (void**)&dv_anchor[0], NULL,

	           s->sys->difseg_size * 27);

    emms_c();

    /* return image */

    *data_size = sizeof(AVFrame);

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

    return s->sys->frame_size;

}


rdt_parse_packet (PayloadContext *rdt, AVStream *st,

                  AVPacket *pkt, uint32_t *timestamp,

                  const uint8_t *buf, int len, int flags)

{

    int seq = 1, res;

    ByteIOContext pb;

    if (rdt->audio_pkt_cnt == 0) {

        int pos;

        init_put_byte(&pb, buf, len, 0, NULL, NULL, NULL, NULL);

        flags = (flags & PKT_FLAG_KEY) ? 2 : 0;

        res = ff_rm_parse_packet (rdt->rmctx, &pb, st, rdt->rmst[0], len, pkt,

                                  &seq, &flags, timestamp);

        pos = url_ftell(&pb);

        if (res < 0)

            return res;

        rdt->audio_pkt_cnt[st->id] = res;

        if (rdt->audio_pkt_cnt[st->id] > 0 &&

            st->codec->codec_id == CODEC_ID_AAC) {

            memcpy (rdt->buffer, buf + pos, len - pos);

            rdt->rmctx->pb = av_alloc_put_byte (rdt->buffer, len - pos, 0,

                                                NULL, NULL, NULL, NULL);

        }

    } else {

        ff_rm_retrieve_cache (rdt->rmctx, rdt->rmctx->pb, st, rdt->rmst[0], pkt);

        if (rdt->audio_pkt_cnt[st->id] == 0 &&

            st->codec->codec_id == CODEC_ID_AAC)

            av_freep(&rdt->rmctx->pb);

    }

    pkt->stream_index = st->index;

    pkt->pts = *timestamp;

    return rdt->audio_pkt_cnt[st->id] > 0;

}


static void FUNC(hevc_v_loop_filter_luma)(uint8_t *pix, ptrdiff_t stride,

                                          int *beta, int *tc, uint8_t *no_p,

                                          uint8_t *no_q)

{

    FUNC(hevc_loop_filter_luma)(pix, sizeof(pixel), stride,

                                beta, tc, no_p, no_q);

}


static int http_server(void)

{

    int server_fd, ret, rtsp_server_fd, delay, delay1;

    struct pollfd poll_table[HTTP_MAX_CONNECTIONS + 2], *poll_entry;

    HTTPContext *c, *c_next;

    server_fd = socket_open_listen(&my_http_addr);

    if (server_fd < 0)

        return -1;

    rtsp_server_fd = socket_open_listen(&my_rtsp_addr);

    if (rtsp_server_fd < 0)

        return -1;

    http_log("ffserver started.\n");

    start_children(first_feed);

    first_http_ctx = NULL;

    nb_connections = 0;

    start_multicast();

    for(;;) {

        poll_entry = poll_table;

        poll_entry->fd = server_fd;

        poll_entry->events = POLLIN;

        poll_entry++;

        poll_entry->fd = rtsp_server_fd;

        poll_entry->events = POLLIN;

        poll_entry++;

        /* wait for events on each HTTP handle */

        c = first_http_ctx;

        delay = 1000;

        while (c != NULL) {

            int fd;

            fd = c->fd;

            switch(c->state) {

            case HTTPSTATE_SEND_HEADER:

            case RTSPSTATE_SEND_REPLY:

            case RTSPSTATE_SEND_PACKET:

                c->poll_entry = poll_entry;

                poll_entry->fd = fd;

                poll_entry->events = POLLOUT;

                poll_entry++;

                break;

            case HTTPSTATE_SEND_DATA_HEADER:

            case HTTPSTATE_SEND_DATA:

            case HTTPSTATE_SEND_DATA_TRAILER:

                if (!c->is_packetized) {

                    /* for TCP, we output as much as we can (may need to put a limit) */

                    c->poll_entry = poll_entry;

                    poll_entry->fd = fd;

                    poll_entry->events = POLLOUT;

                    poll_entry++;

                } else {

                    /* when ffserver is doing the timing, we work by

                       looking at which packet need to be sent every

                       10 ms */

                    delay1 = 10; /* one tick wait XXX: 10 ms assumed */

                    if (delay1 < delay)

                        delay = delay1;

                }

                break;

            case HTTPSTATE_WAIT_REQUEST:

            case HTTPSTATE_RECEIVE_DATA:

            case HTTPSTATE_WAIT_FEED:

            case RTSPSTATE_WAIT_REQUEST:

                /* need to catch errors */

                c->poll_entry = poll_entry;

                poll_entry->fd = fd;

                poll_entry->events = POLLIN;/* Maybe this will work */

                poll_entry++;

                break;

            default:

                c->poll_entry = NULL;

                break;

            }

            c = c->next;

        }

        /* wait for an event on one connection. We poll at least every

           second to handle timeouts */

        do {

            ret = poll(poll_table, poll_entry - poll_table, delay);

            if (ret < 0 && errno != EAGAIN && errno != EINTR)

                return -1;

        } while (ret <= 0);

        cur_time = av_gettime() / 1000;

        if (need_to_start_children) {

            need_to_start_children = 0;

            start_children(first_feed);

        }

        /* now handle the events */

        for(c = first_http_ctx; c != NULL; c = c_next) {

            c_next = c->next;

            if (handle_connection(c) < 0) {

                /* close and free the connection */

                log_connection(c);

                close_connection(c);

            }

        }

        poll_entry = poll_table;

        /* new HTTP connection request ? */

        if (poll_entry->revents & POLLIN) {

            new_connection(server_fd, 0);

        }

        poll_entry++;

        /* new RTSP connection request ? */

        if (poll_entry->revents & POLLIN) {

            new_connection(rtsp_server_fd, 1);

        }

    }

}


static int h264_field_start(H264Context *h, const H264SliceContext *sl,

                            const H2645NAL *nal, int first_slice)

{

    int i;

    const SPS *sps;

    int last_pic_structure, last_pic_droppable, ret;

    ret = h264_init_ps(h, sl, first_slice);

    if (ret < 0)

        return ret;

    sps = h->ps.sps;

    last_pic_droppable   = h->droppable;

    last_pic_structure   = h->picture_structure;

    h->droppable         = (nal->ref_idc == 0);

    h->picture_structure = sl->picture_structure;

    h->poc.frame_num        = sl->frame_num;

    h->poc.poc_lsb          = sl->poc_lsb;

    h->poc.delta_poc_bottom = sl->delta_poc_bottom;

    h->poc.delta_poc[0]     = sl->delta_poc[0];

    h->poc.delta_poc[1]     = sl->delta_poc[1];

    /* Shorten frame num gaps so we don't have to allocate reference

     * frames just to throw them away */

    if (h->poc.frame_num != h->poc.prev_frame_num) {

        int unwrap_prev_frame_num = h->poc.prev_frame_num;

        int max_frame_num         = 1 << sps->log2_max_frame_num;

        if (unwrap_prev_frame_num > h->poc.frame_num)

            unwrap_prev_frame_num -= max_frame_num;

        if ((h->poc.frame_num - unwrap_prev_frame_num) > sps->ref_frame_count) {

            unwrap_prev_frame_num = (h->poc.frame_num - sps->ref_frame_count) - 1;

            if (unwrap_prev_frame_num < 0)

                unwrap_prev_frame_num += max_frame_num;

            h->poc.prev_frame_num = unwrap_prev_frame_num;

        }

    }

    /* See if we have a decoded first field looking for a pair...

     * Here, we're using that to see if we should mark previously

     * decode frames as "finished".

     * We have to do that before the "dummy" in-between frame allocation,

     * since that can modify h->cur_pic_ptr. */

    if (h->first_field) {

        av_assert0(h->cur_pic_ptr);

        av_assert0(h->cur_pic_ptr->f->buf[0]);

        assert(h->cur_pic_ptr->reference != DELAYED_PIC_REF);

        /* Mark old field/frame as completed */

        if (h->cur_pic_ptr->tf.owner == h->avctx) {

            ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,

                                      last_pic_structure == PICT_BOTTOM_FIELD);

        }

        /* figure out if we have a complementary field pair */

        if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) {

            /* Previous field is unmatched. Don't display it, but let it

             * remain for reference if marked as such. */

            if (last_pic_structure != PICT_FRAME) {

                ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,

                                          last_pic_structure == PICT_TOP_FIELD);

            }

        } else {

            if (h->cur_pic_ptr->frame_num != h->poc.frame_num) {

                /* This and previous field were reference, but had

                 * different frame_nums. Consider this field first in

                 * pair. Throw away previous field except for reference

                 * purposes. */

                if (last_pic_structure != PICT_FRAME) {

                    ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,

                                              last_pic_structure == PICT_TOP_FIELD);

                }

            } else {

                /* Second field in complementary pair */

                if (!((last_pic_structure   == PICT_TOP_FIELD &&

                       h->picture_structure == PICT_BOTTOM_FIELD) ||

                      (last_pic_structure   == PICT_BOTTOM_FIELD &&

                       h->picture_structure == PICT_TOP_FIELD))) {

                    av_log(h->avctx, AV_LOG_ERROR,

                           "Invalid field mode combination %d/%d\n",

                           last_pic_structure, h->picture_structure);

                    h->picture_structure = last_pic_structure;

                    h->droppable         = last_pic_droppable;

                    return AVERROR_INVALIDDATA;

                } else if (last_pic_droppable != h->droppable) {

                    avpriv_request_sample(h->avctx,

                                          "Found reference and non-reference fields in the same frame, which");

                    h->picture_structure = last_pic_structure;

                    h->droppable         = last_pic_droppable;

                    return AVERROR_PATCHWELCOME;

                }

            }

        }

    }

    while (h->poc.frame_num != h->poc.prev_frame_num && !h->first_field &&

           h->poc.frame_num != (h->poc.prev_frame_num + 1) % (1 << sps->log2_max_frame_num)) {

        H264Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;

        av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",

               h->poc.frame_num, h->poc.prev_frame_num);

        if (!sps->gaps_in_frame_num_allowed_flag)

            for(i=0; i<FF_ARRAY_ELEMS(h->last_pocs); i++)

                h->last_pocs[i] = INT_MIN;

        ret = h264_frame_start(h);

        if (ret < 0) {

            h->first_field = 0;

            return ret;

        }

        h->poc.prev_frame_num++;

        h->poc.prev_frame_num        %= 1 << sps->log2_max_frame_num;

        h->cur_pic_ptr->frame_num = h->poc.prev_frame_num;

        h->cur_pic_ptr->invalid_gap = !sps->gaps_in_frame_num_allowed_flag;

        ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);

        ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);

        h->explicit_ref_marking = 0;

        ret = ff_h264_execute_ref_pic_marking(h);

        if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))

            return ret;

        /* Error concealment: If a ref is missing, copy the previous ref

         * in its place.

         * FIXME: Avoiding a memcpy would be nice, but ref handling makes

         * many assumptions about there being no actual duplicates.

         * FIXME: This does not copy padding for out-of-frame motion

         * vectors.  Given we are concealing a lost frame, this probably

         * is not noticeable by comparison, but it should be fixed. */

        if (h->short_ref_count) {

            if (prev &&

                h->short_ref[0]->f->width == prev->f->width &&

                h->short_ref[0]->f->height == prev->f->height &&

                h->short_ref[0]->f->format == prev->f->format) {

                ff_thread_await_progress(&prev->tf, INT_MAX, 0);

                if (prev->field_picture)

                    ff_thread_await_progress(&prev->tf, INT_MAX, 1);

                av_image_copy(h->short_ref[0]->f->data,

                              h->short_ref[0]->f->linesize,

                              (const uint8_t **)prev->f->data,

                              prev->f->linesize,

                              prev->f->format,

                              prev->f->width,

                              prev->f->height);

                h->short_ref[0]->poc = prev->poc + 2;

            }

            h->short_ref[0]->frame_num = h->poc.prev_frame_num;

        }

    }

    /* See if we have a decoded first field looking for a pair...

     * We're using that to see whether to continue decoding in that

     * frame, or to allocate a new one. */

    if (h->first_field) {

        av_assert0(h->cur_pic_ptr);

        av_assert0(h->cur_pic_ptr->f->buf[0]);

        assert(h->cur_pic_ptr->reference != DELAYED_PIC_REF);

        /* figure out if we have a complementary field pair */

        if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) {

            /* Previous field is unmatched. Don't display it, but let it

             * remain for reference if marked as such. */

            h->missing_fields ++;

            h->cur_pic_ptr = NULL;

            h->first_field = FIELD_PICTURE(h);

        } else {

            h->missing_fields = 0;

            if (h->cur_pic_ptr->frame_num != h->poc.frame_num) {

                ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,

                                          h->picture_structure==PICT_BOTTOM_FIELD);

                /* This and the previous field had different frame_nums.

                 * Consider this field first in pair. Throw away previous

                 * one except for reference purposes. */

                h->first_field = 1;

                h->cur_pic_ptr = NULL;

            } else {

                /* Second field in complementary pair */

                h->first_field = 0;

            }

        }

    } else {

        /* Frame or first field in a potentially complementary pair */

        h->first_field = FIELD_PICTURE(h);

    }

    if (!FIELD_PICTURE(h) || h->first_field) {

        if (h264_frame_start(h) < 0) {

            h->first_field = 0;

            return AVERROR_INVALIDDATA;

        }

    } else {

        release_unused_pictures(h, 0);

    }

    /* Some macroblocks can be accessed before they're available in case

    * of lost slices, MBAFF or threading. */

    if (FIELD_PICTURE(h)) {

        for(i = (h->picture_structure == PICT_BOTTOM_FIELD); i<h->mb_height; i++)

            memset(h->slice_table + i*h->mb_stride, -1, (h->mb_stride - (i+1==h->mb_height)) * sizeof(*h->slice_table));

    } else {

        memset(h->slice_table, -1,

            (h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table));

    }

    ff_h264_init_poc(h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc,

                     h->ps.sps, &h->poc, h->picture_structure, nal->ref_idc);

    memcpy(h->mmco, sl->mmco, sl->nb_mmco * sizeof(*h->mmco));

    h->nb_mmco = sl->nb_mmco;

    h->explicit_ref_marking = sl->explicit_ref_marking;

    h->picture_idr = nal->type == H264_NAL_IDR_SLICE;

    if (h->sei.recovery_point.recovery_frame_cnt >= 0) {

        const int sei_recovery_frame_cnt = h->sei.recovery_point.recovery_frame_cnt;

        if (h->poc.frame_num != sei_recovery_frame_cnt || sl->slice_type_nos != AV_PICTURE_TYPE_I)

            h->valid_recovery_point = 1;

        if (   h->recovery_frame < 0

            || av_mod_uintp2(h->recovery_frame - h->poc.frame_num, h->ps.sps->log2_max_frame_num) > sei_recovery_frame_cnt) {

            h->recovery_frame = av_mod_uintp2(h->poc.frame_num + sei_recovery_frame_cnt, h->ps.sps->log2_max_frame_num);

            if (!h->valid_recovery_point)

                h->recovery_frame = h->poc.frame_num;

        }

    }

    h->cur_pic_ptr->f->key_frame |= (nal->type == H264_NAL_IDR_SLICE);

    if (nal->type == H264_NAL_IDR_SLICE ||

        (h->recovery_frame == h->poc.frame_num && nal->ref_idc)) {

        h->recovery_frame         = -1;

        h->cur_pic_ptr->recovered = 1;

    }

    // If we have an IDR, all frames after it in decoded order are

    // "recovered".

    if (nal->type == H264_NAL_IDR_SLICE)

        h->frame_recovered |= FRAME_RECOVERED_IDR;

#if 1

    h->cur_pic_ptr->recovered |= h->frame_recovered;

#else

    h->cur_pic_ptr->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_IDR);

#endif

    /* Set the frame properties/side data. Only done for the second field in

     * field coded frames, since some SEI information is present for each field

     * and is merged by the SEI parsing code. */

    if (!FIELD_PICTURE(h) || !h->first_field || h->missing_fields > 1) {

        ret = h264_export_frame_props(h);

        if (ret < 0)

            return ret;

        ret = h264_select_output_frame(h);

        if (ret < 0)

            return ret;

    }

    return 0;

}


void fork_start(void)

{

    mmap_fork_start();

    qemu_mutex_lock(&tb_ctx.tb_lock);

    cpu_list_lock();

}


static int config_output(AVFilterLink *outlink)

{

    AVFilterContext *ctx = outlink->src;

    LIBVMAFContext *s = ctx->priv;

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

    int ret;

    outlink->w = mainlink->w;

    outlink->h = mainlink->h;

    outlink->time_base = mainlink->time_base;

    outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio;

    outlink->frame_rate = mainlink->frame_rate;

    if ((ret = ff_dualinput_init(ctx, &s->dinput)) < 0)

        return ret;

    return 0;

}


void h263_encode_mb(MpegEncContext * s,

		    DCTELEM block[6][64],

		    int motion_x, int motion_y)

{

    int cbpc, cbpy, i, cbp, pred_x, pred_y;

    //    printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);

   if (!s->mb_intra) {

	   /* compute cbp */

	   cbp = 0;

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

	      if (s->block_last_index[i] >= 0)

		   cbp |= 1 << (5 - i);

	   }

	   if ((cbp | motion_x | motion_y) == 0) {

	      /* skip macroblock */

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

	      return;

	   }

	   put_bits(&s->pb, 1, 0);	/* mb coded */

	   cbpc = cbp & 3;

	   put_bits(&s->pb,

		inter_MCBPC_bits[cbpc],

		inter_MCBPC_code[cbpc]);

	   cbpy = cbp >> 2;

	   cbpy ^= 0xf;

	   put_bits(&s->pb, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]);

	   /* motion vectors: 16x16 mode only now */

      h263_pred_motion(s, 0, &pred_x, &pred_y);

      if (!umvplus) {

         h263_encode_motion(s, motion_x - pred_x);

         h263_encode_motion(s, motion_y - pred_y);

      }

      else {

         h263p_encode_umotion(s, motion_x - pred_x);

         h263p_encode_umotion(s, motion_y - pred_y);

         if (((motion_x - pred_x) == 1) && ((motion_y - pred_y) == 1))

            /* To prevent Start Code emulation */

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

      }

   } else {

	/* compute cbp */

	cbp = 0;

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

	    if (s->block_last_index[i] >= 1)

		cbp |= 1 << (5 - i);

	}

	cbpc = cbp & 3;

	if (s->pict_type == I_TYPE) {

	    put_bits(&s->pb,

		     intra_MCBPC_bits[cbpc],

		     intra_MCBPC_code[cbpc]);

	} else {

	    put_bits(&s->pb, 1, 0);	/* mb coded */

	    put_bits(&s->pb,

		     inter_MCBPC_bits[cbpc + 4],

		     inter_MCBPC_code[cbpc + 4]);

	}

	if (s->h263_pred) {

	    /* XXX: currently, we do not try to use ac prediction */

	    put_bits(&s->pb, 1, 0);	/* no ac prediction */

	}

	cbpy = cbp >> 2;

	put_bits(&s->pb, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]);

    }

    /* encode each block */

    if (s->h263_pred) {

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

	    mpeg4_encode_block(s, block[i], i);

	}

    } else {

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

	    h263_encode_block(s, block[i], i);

	}

    }

}


static int decode_band(IVI5DecContext *ctx, int plane_num,

                       IVIBandDesc *band, AVCodecContext *avctx)

{

    int         result, i, t, idx1, idx2;

    IVITile     *tile;

    band->buf     = band->bufs[ctx->dst_buf];

    band->ref_buf = band->bufs[ctx->ref_buf];

    band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3);

    result = decode_band_hdr(ctx, band, avctx);

    if (result) {

        av_log(avctx, AV_LOG_ERROR, "Error while decoding band header: %d\n",

               result);

        return -1;

    }

    if (band->is_empty) {

        av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n");

        return -1;

    }

    band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel];

    /* apply corrections to the selected rvmap table if present */

    for (i = 0; i < band->num_corr; i++) {

        idx1 = band->corr[i*2];

        idx2 = band->corr[i*2+1];

        FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);

        FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);

    }

    for (t = 0; t < band->num_tiles; t++) {

        tile = &band->tiles[t];

        tile->is_empty = get_bits1(&ctx->gb);

        if (tile->is_empty) {

            ff_ivi_process_empty_tile(avctx, band, tile,

                                      (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3));

            align_get_bits(&ctx->gb);

        } else {

            tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);

            result = decode_mb_info(ctx, band, tile, avctx);

            if (result < 0)

                break;

            if (band->blk_size == 8) {

                band->intra_base  = &ivi5_base_quant_8x8_intra[band->quant_mat][0];

                band->inter_base  = &ivi5_base_quant_8x8_inter[band->quant_mat][0];

                band->intra_scale = &ivi5_scale_quant_8x8_intra[band->quant_mat][0];

                band->inter_scale = &ivi5_scale_quant_8x8_inter[band->quant_mat][0];

            } else {

                band->intra_base  = ivi5_base_quant_4x4_intra;

                band->inter_base  = ivi5_base_quant_4x4_inter;

                band->intra_scale = ivi5_scale_quant_4x4_intra;

                band->inter_scale = ivi5_scale_quant_4x4_inter;

            }

            result = ff_ivi_decode_blocks(&ctx->gb, band, tile);

            if (result < 0) {

                av_log(avctx, AV_LOG_ERROR, "Corrupted blocks data encountered!\n");

                break;

            }

        }

    }

    /* restore the selected rvmap table by applying its corrections in reverse order */

    for (i = band->num_corr-1; i >= 0; i--) {

        idx1 = band->corr[i*2];

        idx2 = band->corr[i*2+1];

        FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);

        FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);

    }

#if IVI_DEBUG

    if (band->checksum_present) {

        uint16_t chksum = ivi_calc_band_checksum(band);

        if (chksum != band->checksum) {

            av_log(avctx, AV_LOG_ERROR,

                   "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n",

                   band->plane, band->band_num, band->checksum, chksum);

        }

    }

#endif

    return result;

}


static int select_reference_stream(AVFormatContext *s)

{

    SegmentContext *seg = s->priv_data;

    int ret, i;

    seg->reference_stream_index = -1;

    if (!strcmp(seg->reference_stream_specifier, "auto")) {

        /* select first index of type with highest priority */

        int type_index_map[AVMEDIA_TYPE_NB];

        static const enum AVMediaType type_priority_list[] = {

            AVMEDIA_TYPE_VIDEO,

            AVMEDIA_TYPE_AUDIO,

            AVMEDIA_TYPE_SUBTITLE,

            AVMEDIA_TYPE_DATA,

            AVMEDIA_TYPE_ATTACHMENT

        };

        enum AVMediaType type;

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

            type_index_map[i] = -1;

        /* select first index for each type */

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

            type = s->streams[i]->codec->codec_type;

            if ((unsigned)type < AVMEDIA_TYPE_NB && type_index_map[type] == -1

                /* ignore attached pictures/cover art streams */

                && !(s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC))

                type_index_map[type] = i;

        }

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

            type = type_priority_list[i];

            if ((seg->reference_stream_index = type_index_map[type]) >= 0)

                break;

        }

    } else {

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

            ret = avformat_match_stream_specifier(s, s->streams[i],

                                                  seg->reference_stream_specifier);

            if (ret < 0)

                break;

            if (ret > 0) {

                seg->reference_stream_index = i;

                break;

            }

        }

    }

    if (seg->reference_stream_index < 0) {

        av_log(s, AV_LOG_ERROR, "Could not select stream matching identifier '%s'\n",

               seg->reference_stream_specifier);

        return AVERROR(EINVAL);

    }

    return 0;

}