static int dca_decode_frame(AVCodecContext * avctx,
                            void *data, int *data_size,
                            AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    int i;
    int16_t *samples = data;
    DCAContext *s = avctx->priv_data;
    int channels;
    s->dca_buffer_size = dca_convert_bitstream(buf, buf_size, s->dca_buffer, DCA_MAX_FRAME_SIZE);
    if (s->dca_buffer_size == -1) {
        av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n");
    }
    init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8);
    if (dca_parse_frame_header(s) < 0) {
        //seems like the frame is corrupt, try with the next one
        *data_size=0;
        return buf_size;
    }
    //set AVCodec values with parsed data
    avctx->sample_rate = s->sample_rate;
    avctx->bit_rate = s->bit_rate;
    channels = s->prim_channels + !!s->lfe;
    if (s->amode<16) {
        avctx->channel_layout = dca_core_channel_layout[s->amode];
        if (s->lfe) {
            avctx->channel_layout |= CH_LOW_FREQUENCY;
            s->channel_order_tab = dca_channel_reorder_lfe[s->amode];
        } else
            s->channel_order_tab = dca_channel_reorder_nolfe[s->amode];
        if(avctx->request_channels == 2 && s->prim_channels > 2) {
            channels = 2;
            s->output = DCA_STEREO;
            avctx->channel_layout = CH_LAYOUT_STEREO;
        }
    } else {
        av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n",s->amode);
    }
    /* There is nothing that prevents a dts frame to change channel configuration
       but FFmpeg doesn't support that so only set the channels if it is previously
       unset. Ideally during the first probe for channels the crc should be checked
       and only set avctx->channels when the crc is ok. Right now the decoder could
       set the channels based on a broken first frame.*/
    if (!avctx->channels)
        avctx->channels = channels;
    if(*data_size < (s->sample_blocks / 8) * 256 * sizeof(int16_t) * channels)
    *data_size = 256 / 8 * s->sample_blocks * sizeof(int16_t) * channels;
    for (i = 0; i < (s->sample_blocks / 8); i++) {
        dca_decode_block(s);
        s->dsp.float_to_int16_interleave(samples, s->samples_chanptr, 256, channels);
        samples += 256 * channels;
    }
    return buf_size;
}


static void dmg_close(BlockDriverState *bs)

{

    BDRVDMGState *s = bs->opaque;

    g_free(s->types);

    g_free(s->offsets);

    g_free(s->lengths);

    g_free(s->sectors);

    g_free(s->sectorcounts);

    g_free(s->compressed_chunk);

    g_free(s->uncompressed_chunk);

    inflateEnd(&s->zstream);

}


int gdbserver_start(const char *device)

{

    GDBState *s;

    char gdbstub_device_name[128];

    CharDriverState *chr = NULL;

    CharDriverState *mon_chr;

    if (!device)

        return -1;

    if (strcmp(device, "none") != 0) {

        if (strstart(device, "tcp:", NULL)) {

            /* enforce required TCP attributes */

            snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),

                     "%s,nowait,nodelay,server", device);

            device = gdbstub_device_name;

        }

#ifndef _WIN32

        else if (strcmp(device, "stdio") == 0) {

            struct sigaction act;

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

            act.sa_handler = gdb_sigterm_handler;

            sigaction(SIGINT, &act, NULL);

        }

#endif

        chr = qemu_chr_new("gdb", device, NULL);

        if (!chr)

            return -1;

        qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,

                              gdb_chr_event, NULL);

    }

    s = gdbserver_state;

    if (!s) {

        s = g_malloc0(sizeof(GDBState));

        gdbserver_state = s;

        qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);

        /* Initialize a monitor terminal for gdb */

        mon_chr = g_malloc0(sizeof(*mon_chr));

        mon_chr->chr_write = gdb_monitor_write;

        monitor_init(mon_chr, 0);

    } else {

        if (s->chr)

            qemu_chr_delete(s->chr);

        mon_chr = s->mon_chr;

        memset(s, 0, sizeof(GDBState));

    }

    s->c_cpu = first_cpu;

    s->g_cpu = first_cpu;

    s->chr = chr;

    s->state = chr ? RS_IDLE : RS_INACTIVE;

    s->mon_chr = mon_chr;

    s->current_syscall_cb = NULL;

    return 0;

}


static int opus_packet(AVFormatContext *avf, int idx)

{

    struct ogg *ogg              = avf->priv_data;

    struct ogg_stream *os        = &ogg->streams[idx];

    AVStream *st                 = avf->streams[idx];

    struct oggopus_private *priv = os->private;

    uint8_t *packet              = os->buf + os->pstart;

    int ret;

    if (!os->psize)

        return AVERROR_INVALIDDATA;

    if (os->granule > INT64_MAX - UINT32_MAX) {

        av_log(avf, AV_LOG_ERROR, "Unsupported huge granule pos %"PRId64 "\n", os->granule);

        return AVERROR_INVALIDDATA;

    }

    if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {

        int seg, d;

        int duration;

        uint8_t *last_pkt  = os->buf + os->pstart;

        uint8_t *next_pkt  = last_pkt;

        duration = 0;

        seg = os->segp;

        d = opus_duration(last_pkt, os->psize);

        if (d < 0) {

            os->pflags |= AV_PKT_FLAG_CORRUPT;

            return 0;

        }

        duration += d;

        last_pkt = next_pkt =  next_pkt + os->psize;

        for (; seg < os->nsegs; seg++) {

            next_pkt += os->segments[seg];

            if (os->segments[seg] < 255 && next_pkt != last_pkt) {

                int d = opus_duration(last_pkt, next_pkt - last_pkt);

                if (d > 0)

                    duration += d;

                last_pkt = next_pkt;

            }

        }

        os->lastpts                 =

        os->lastdts                 = os->granule - duration;

    }

    if ((ret = opus_duration(packet, os->psize)) < 0)

        return ret;

    os->pduration = ret;

    if (os->lastpts != AV_NOPTS_VALUE) {

        if (st->start_time == AV_NOPTS_VALUE)

            st->start_time = os->lastpts;

        priv->cur_dts = os->lastdts = os->lastpts -= priv->pre_skip;

    }

    priv->cur_dts += os->pduration;

    if ((os->flags & OGG_FLAG_EOS)) {

        int64_t skip = priv->cur_dts - os->granule + priv->pre_skip;

        skip = FFMIN(skip, os->pduration);

        if (skip > 0) {

            os->pduration = skip < os->pduration ? os->pduration - skip : 1;

            os->end_trimming = skip;

            av_log(avf, AV_LOG_DEBUG,

                   "Last packet was truncated to %d due to end trimming.\n",

                   os->pduration);

        }

    }

    return 0;

}


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

{

    unsigned char *destptr_bak = destptr;

    unsigned char *destptr_end = destptr + destsize;

    unsigned char mask = 0;

    unsigned char maskbit = 0;

    unsigned int ofs, cnt;

    while (srclen > 0 && destptr < destptr_end) {

        if (maskbit == 0) {

            mask = *srcptr++;

            maskbit = 8;

            srclen--;

            continue;

        }

        if ((mask & (1 << (--maskbit))) == 0) {

            if (destptr + 4 > destptr_end)

                break;

            memcpy(destptr, srcptr, 4);

            srclen -= 4;

            destptr += 4;

            srcptr += 4;

        } else {

            ofs = *srcptr++;

            cnt = *srcptr++;

            ofs += cnt * 256;

            cnt = ((cnt >> 3) & 0x1f) + 1;

            ofs &= 0x7ff;

            srclen -= 2;

            cnt *= 4;

            if (destptr + cnt > destptr_end) {

                cnt =  destptr_end - destptr;

            }

            for (; cnt > 0; cnt--) {

                *destptr = *(destptr - ofs);

                destptr++;

            }

        }

    }

    return destptr - destptr_bak;

}


static int decode_codestream(Jpeg2000DecoderContext *s)

{

    Jpeg2000CodingStyle *codsty = s->codsty;

    Jpeg2000QuantStyle  *qntsty = s->qntsty;

    uint8_t *properties = s->properties;

    for (;;){

        int oldpos, marker, len, ret = 0;

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

            av_log(s->avctx, AV_LOG_ERROR, "Missing EOC\n");

            break;

        }

        marker = bytestream2_get_be16u(&s->g);

        av_dlog(s->avctx, "marker 0x%.4X at pos 0x%x\n", marker, bytestream2_tell(&s->g) - 4);

        oldpos = bytestream2_tell(&s->g);

        if (marker == JPEG2000_SOD){

            Jpeg2000Tile *tile = s->tile + s->curtileno;

            if (ret = init_tile(s, s->curtileno)) {

                av_log(s->avctx, AV_LOG_ERROR, "tile initialization failed\n");

                return ret;

            }

            if (ret = jpeg2000_decode_packets(s, tile)) {

                av_log(s->avctx, AV_LOG_ERROR, "packets decoding failed\n");

                return ret;

            }

            continue;

        }

        if (marker == JPEG2000_EOC)

            break;

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

            return AVERROR(EINVAL);

        len = bytestream2_get_be16u(&s->g);

        switch (marker){

        case JPEG2000_SIZ:

            ret = get_siz(s);

            break;

        case JPEG2000_COC:

            ret = get_coc(s, codsty, properties);

            break;

        case JPEG2000_COD:

            ret = get_cod(s, codsty, properties);

            break;

        case JPEG2000_QCC:

            ret = get_qcc(s, len, qntsty, properties);

            break;

        case JPEG2000_QCD:

            ret = get_qcd(s, len, qntsty, properties);

            break;

        case JPEG2000_SOT:

            if (!(ret = get_sot(s))){

                codsty = s->tile[s->curtileno].codsty;

                qntsty = s->tile[s->curtileno].qntsty;

                properties = s->tile[s->curtileno].properties;

            }

            break;

        case JPEG2000_COM:

            // the comment is ignored

            bytestream2_skip(&s->g, len - 2);

            break;

        default:

            av_log(s->avctx, AV_LOG_ERROR, "unsupported marker 0x%.4X at pos 0x%x\n", marker, bytestream2_tell(&s->g) - 4);

            bytestream2_skip(&s->g, len - 2);

            break;

        }

        if (bytestream2_tell(&s->g) - oldpos != len || ret){

            av_log(s->avctx, AV_LOG_ERROR, "error during processing marker segment %.4x\n", marker);

            return ret ? ret : -1;

        }

    }

    return 0;

}


void do_mulldo (void)

{

    int64_t th;

    uint64_t tl;

    muls64(&tl, &th, T0, T1);

    if (likely(th == 0)) {

        xer_ov = 0;

    } else {

        xer_ov = 1;

        xer_so = 1;

    }

    T0 = (int64_t)tl;

}


static int decode_unit(SCPRContext *s, PixelModel *pixel, unsigned step, unsigned *rval)

{

    GetByteContext *gb = &s->gb;

    RangeCoder *rc = &s->rc;

    unsigned totfr = pixel->total_freq;

    unsigned value, x = 0, cumfr = 0, cnt_x = 0;

    int i, j, ret, c, cnt_c;

    if ((ret = s->get_freq(rc, totfr, &value)) < 0)

        return ret;

    while (x < 16) {

        cnt_x = pixel->lookup[x];

        if (value >= cumfr + cnt_x)

            cumfr += cnt_x;

        else

            break;

        x++;

    }

    c = x * 16;

    cnt_c = 0;

    while (c < 256) {

        cnt_c = pixel->freq[c];

        if (value >= cumfr + cnt_c)

            cumfr += cnt_c;

        else

            break;

        c++;

    }

    s->decode(gb, rc, cumfr, cnt_c, totfr);

    pixel->freq[c] = cnt_c + step;

    pixel->lookup[x] = cnt_x + step;

    totfr += step;

    if (totfr > BOT) {

        totfr = 0;

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

            unsigned nc = (pixel->freq[i] >> 1) + 1;

            pixel->freq[i] = nc;

            totfr += nc;

        }

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

            unsigned sum = 0;

            unsigned i16_17 = i << 4;

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

                sum += pixel->freq[i16_17 + j];

            pixel->lookup[i] = sum;

        }

    }

    pixel->total_freq = totfr;

    *rval = c & s->cbits;

    return 0;

}


static void sbr_env_estimate(float (*e_curr)[48], float X_high[64][40][2],

                             SpectralBandReplication *sbr, SBRData *ch_data)

{

    int e, i, m;

    if (sbr->bs_interpol_freq) {

        for (e = 0; e < ch_data->bs_num_env; e++) {

            const float recip_env_size = 0.5f / (ch_data->t_env[e + 1] - ch_data->t_env[e]);

            int ilb = ch_data->t_env[e]     * 2 + ENVELOPE_ADJUSTMENT_OFFSET;

            int iub = ch_data->t_env[e + 1] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;

            for (m = 0; m < sbr->m[1]; m++) {

                float sum = 0.0f;

                for (i = ilb; i < iub; i++) {

                    sum += X_high[m + sbr->kx[1]][i][0] * X_high[m + sbr->kx[1]][i][0] +

                           X_high[m + sbr->kx[1]][i][1] * X_high[m + sbr->kx[1]][i][1];

                }

                e_curr[e][m] = sum * recip_env_size;

            }

        }

    } else {

        int k, p;

        for (e = 0; e < ch_data->bs_num_env; e++) {

            const int env_size = 2 * (ch_data->t_env[e + 1] - ch_data->t_env[e]);

            int ilb = ch_data->t_env[e]     * 2 + ENVELOPE_ADJUSTMENT_OFFSET;

            int iub = ch_data->t_env[e + 1] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;

            const uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow;

            for (p = 0; p < sbr->n[ch_data->bs_freq_res[e + 1]]; p++) {

                float sum = 0.0f;

                const int den = env_size * (table[p + 1] - table[p]);

                for (k = table[p]; k < table[p + 1]; k++) {

                    for (i = ilb; i < iub; i++) {

                        sum += X_high[k][i][0] * X_high[k][i][0] +

                               X_high[k][i][1] * X_high[k][i][1];

                    }

                }

                sum /= den;

                for (k = table[p]; k < table[p + 1]; k++) {

                    e_curr[e][k - sbr->kx[1]] = sum;

                }

            }

        }

    }

}


static int test_scalarproduct_float(AVFloatDSPContext *fdsp, AVFloatDSPContext *cdsp,

                                    const float *v1, const float *v2)

{

    float cprod, oprod;

    int ret;

    cprod = cdsp->scalarproduct_float(v1, v2, LEN);

    oprod = fdsp->scalarproduct_float(v1, v2, LEN);

    if (ret = compare_floats(&cprod, &oprod, 1, ARBITRARY_SCALARPRODUCT_CONST))

        av_log(NULL, AV_LOG_ERROR, "scalarproduct_float failed\n");

    return ret;

}


static int mov_read_pasp(MOVContext *c, ByteIOContext *pb, MOVAtom atom)

{

    const int num = get_be32(pb);

    const int den = get_be32(pb);

    AVStream * const st = c->fc->streams[c->fc->nb_streams-1];

    if (den != 0) {

        if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default

            (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num))

            av_log(c->fc, AV_LOG_WARNING,

                   "sample aspect ratio already set to %d:%d, overriding by 'pasp' atom\n",

                   st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);

        st->sample_aspect_ratio.num = num;

        st->sample_aspect_ratio.den = den;

    }

    return 0;

}


static void MPV_encode_defaults(MpegEncContext *s){

    static int done=0;

    MPV_common_defaults(s);

    if(!done){

        int i;

        done=1;

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

            default_fcode_tab[i + MAX_MV]= 1;

        }

    }

    s->me.mv_penalty= default_mv_penalty;

    s->fcode_tab= default_fcode_tab;

}


int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,

                             int has_alpha)

{

    const PixFmtInfo *pf, *ps;

    int loss;

    ps = &pix_fmt_info[src_pix_fmt];

    pf = &pix_fmt_info[dst_pix_fmt];

    /* compute loss */

    loss = 0;

    pf = &pix_fmt_info[dst_pix_fmt];

    if (pf->depth < ps->depth)

        loss |= FF_LOSS_DEPTH;

    if (pf->x_chroma_shift >= ps->x_chroma_shift ||

        pf->y_chroma_shift >= ps->y_chroma_shift)

        loss |= FF_LOSS_RESOLUTION;

    switch(pf->color_type) {

    case FF_COLOR_RGB:

        if (ps->color_type != FF_COLOR_RGB &&

            ps->color_type != FF_COLOR_GRAY)

            loss |= FF_LOSS_COLORSPACE;

        break;

    case FF_COLOR_GRAY:

        if (ps->color_type != FF_COLOR_GRAY)

            loss |= FF_LOSS_COLORSPACE;

        break;

    case FF_COLOR_YUV:

        if (ps->color_type != FF_COLOR_YUV)

            loss |= FF_LOSS_COLORSPACE;

        break;

    case FF_COLOR_YUV_JPEG:

        if (ps->color_type != FF_COLOR_YUV_JPEG &&

            ps->color_type != FF_COLOR_YUV)

            loss |= FF_LOSS_COLORSPACE;

        break;

    default:

        /* fail safe test */

        if (ps->color_type != pf->color_type)

            loss |= FF_LOSS_COLORSPACE;

        break;

    }

    if (pf->color_type == FF_COLOR_GRAY &&

        ps->color_type != FF_COLOR_GRAY)

        loss |= FF_LOSS_CHROMA;

    if (!pf->is_alpha && (ps->is_alpha && has_alpha))

        loss |= FF_LOSS_ALPHA;

    if (pf->is_paletted && (!ps->is_paletted && ps->color_type != FF_COLOR_GRAY))

        loss |= FF_LOSS_COLORQUANT;

    return loss;

}


static int ftp_get_file_handle(URLContext *h)

{

    FTPContext *s = h->priv_data;

    av_dlog(h, "ftp protocol get_file_handle\n");

    if (s->conn_data)

        return ffurl_get_file_handle(s->conn_data);

    return AVERROR(EIO);

}


static void sdp_write_header(char *buff, int size, struct sdp_session_level *s)

{

    av_strlcatf(buff, size, "v=%d\r\n"

                            "o=- %d %d IN IPV4 %s\r\n"

                            "t=%d %d\r\n"

                            "s=%s\r\n"

                            "a=tool:libavformat " AV_STRINGIFY(LIBAVFORMAT_VERSION) "\r\n",

                            s->sdp_version,

                            s->id, s->version, s->src_addr,

                            s->start_time, s->end_time,

                            s->name[0] ? s->name : "No Name");

    dest_write(buff, size, s->dst_addr, s->ttl);

}


static int print_device_sources(AVInputFormat *fmt, AVDictionary *opts)

{

    int ret, i;

    AVFormatContext *dev = NULL;

    AVDeviceInfoList *device_list = NULL;

    AVDictionary *tmp_opts = NULL;

    if (!fmt || !fmt->priv_class  || !AV_IS_INPUT_DEVICE(fmt->priv_class->category))

        return AVERROR(EINVAL);

    printf("Audo-detected sources for %s:\n", fmt->name);

    if (!fmt->get_device_list) {

        ret = AVERROR(ENOSYS);

        printf("Cannot list sources. Not implemented.\n");

        goto fail;

    }

    /* TODO: avformat_open_input calls read_header callback which is not necessary.

             Function like avformat_alloc_output_context2 for input could be helpful here. */

    av_dict_copy(&tmp_opts, opts, 0);

    if ((ret = avformat_open_input(&dev, NULL, fmt, &tmp_opts)) < 0) {

        printf("Cannot open device: %s.\n", fmt->name);

        goto fail;

    }

    if ((ret = avdevice_list_devices(dev, &device_list)) < 0) {

        printf("Cannot list sources.\n");

        goto fail;

    }

    for (i = 0; i < device_list->nb_devices; i++) {

        printf("%s %s [%s]\n", device_list->default_device == i ? "*" : " ",

               device_list->devices[i]->device_name, device_list->devices[i]->device_description);

    }

  fail:

    av_dict_free(&tmp_opts);

    avdevice_free_list_devices(&device_list);

    avformat_close_input(&dev);

    return ret;

}


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

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

			    uint8_t *dest, int dstW, int dstY)

{

	int dummy=0;

	switch(c->dstFormat)

	{

#ifdef HAVE_MMX

	case IMGFMT_BGR32:

		{

			asm volatile(

				YSCALEYUV2RGBX

				WRITEBGR32(%4, %5, %%REGa)

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

			   "m" (dummy), "m" (dummy), "m" (dummy),

			   "r" (dest), "m" (dstW)

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

			);

		}

		break;

	case IMGFMT_BGR24:

		{

			asm volatile(

				YSCALEYUV2RGBX

				"lea (%%"REG_a", %%"REG_a", 2), %%"REG_b"\n\t" //FIXME optimize

				"add %4, %%"REG_b"			\n\t"

				WRITEBGR24(%%REGb, %5, %%REGa)

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

			   "m" (dummy), "m" (dummy), "m" (dummy),

			   "r" (dest), "m" (dstW)

			: "%"REG_a, "%"REG_b, "%"REG_d, "%"REG_S //FIXME ebx

			);

		}

		break;

	case IMGFMT_BGR15:

		{

			asm volatile(

				YSCALEYUV2RGBX

		/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

#ifdef DITHER1XBPP

				"paddusb "MANGLE(b5Dither)", %%mm2\n\t"

				"paddusb "MANGLE(g5Dither)", %%mm4\n\t"

				"paddusb "MANGLE(r5Dither)", %%mm5\n\t"

#endif

				WRITEBGR15(%4, %5, %%REGa)

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

			   "m" (dummy), "m" (dummy), "m" (dummy),

			   "r" (dest), "m" (dstW)

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

			);

		}

		break;

	case IMGFMT_BGR16:

		{

			asm volatile(

				YSCALEYUV2RGBX

		/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

#ifdef DITHER1XBPP

				"paddusb "MANGLE(b5Dither)", %%mm2\n\t"

				"paddusb "MANGLE(g6Dither)", %%mm4\n\t"

				"paddusb "MANGLE(r5Dither)", %%mm5\n\t"

#endif

				WRITEBGR16(%4, %5, %%REGa)

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

			   "m" (dummy), "m" (dummy), "m" (dummy),

			   "r" (dest), "m" (dstW)

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

			);

		}

		break;

	case IMGFMT_YUY2:

		{

			asm volatile(

				YSCALEYUV2PACKEDX

		/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

				"psraw $3, %%mm3		\n\t"

				"psraw $3, %%mm4		\n\t"

				"psraw $3, %%mm1		\n\t"

				"psraw $3, %%mm7		\n\t"

				WRITEYUY2(%4, %5, %%REGa)

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

			   "m" (dummy), "m" (dummy), "m" (dummy),

			   "r" (dest), "m" (dstW)

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

			);

		}

		break;

#endif

	default:

#ifdef HAVE_ALTIVEC

		/* The following list of supported dstFormat values should

		   match what's found in the body of altivec_yuv2packedX() */

		if(c->dstFormat==IMGFMT_ABGR  || c->dstFormat==IMGFMT_BGRA  ||

		   c->dstFormat==IMGFMT_BGR24 || c->dstFormat==IMGFMT_RGB24 ||

		   c->dstFormat==IMGFMT_RGBA  || c->dstFormat==IMGFMT_ARGB)

			altivec_yuv2packedX (c, lumFilter, lumSrc, lumFilterSize,

				    chrFilter, chrSrc, chrFilterSize,

				    dest, dstW, dstY);

		else

#endif

			yuv2packedXinC(c, lumFilter, lumSrc, lumFilterSize,

				    chrFilter, chrSrc, chrFilterSize,

				    dest, dstW, dstY);

		break;

	}

}


static int multiple_resample(ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed){
    int i, ret= -1;
    int av_unused mm_flags = av_get_cpu_flags();
    int need_emms= 0;
    if (c->compensation_distance)
        dst_size = FFMIN(dst_size, c->compensation_distance);
    for(i=0; i<dst->ch_count; i++){
#if HAVE_MMXEXT_INLINE
#if HAVE_SSE2_INLINE
             if(c->format == AV_SAMPLE_FMT_S16P && (mm_flags&AV_CPU_FLAG_SSE2)) ret= swri_resample_int16_sse2 (c, (int16_t*)dst->ch[i], (const int16_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
        else
#endif
             if(c->format == AV_SAMPLE_FMT_S16P && (mm_flags&AV_CPU_FLAG_MMX2 )){
                 ret= swri_resample_int16_mmx2 (c, (int16_t*)dst->ch[i], (const int16_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
                 need_emms= 1;
             } else
#endif
             if(c->format == AV_SAMPLE_FMT_S16P) ret= swri_resample_int16(c, (int16_t*)dst->ch[i], (const int16_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
        else if(c->format == AV_SAMPLE_FMT_S32P) ret= swri_resample_int32(c, (int32_t*)dst->ch[i], (const int32_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
#if HAVE_AVX_INLINE
        else if(c->format == AV_SAMPLE_FMT_FLTP && (mm_flags&AV_CPU_FLAG_AVX))
                                                 ret= swri_resample_float_avx (c, (float*)dst->ch[i], (const float*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
#endif
#if HAVE_SSE_INLINE
        else if(c->format == AV_SAMPLE_FMT_FLTP && (mm_flags&AV_CPU_FLAG_SSE))
                                                 ret= swri_resample_float_sse (c, (float*)dst->ch[i], (const float*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
#endif
        else if(c->format == AV_SAMPLE_FMT_FLTP) ret= swri_resample_float(c, (float  *)dst->ch[i], (const float  *)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
#if HAVE_SSE2_INLINE
        else if(c->format == AV_SAMPLE_FMT_DBLP && (mm_flags&AV_CPU_FLAG_SSE2))
                                                 ret= swri_resample_double_sse2(c,(double *)dst->ch[i], (const double *)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
#endif
        else if(c->format == AV_SAMPLE_FMT_DBLP) ret= swri_resample_double(c,(double *)dst->ch[i], (const double *)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
    if(need_emms)
        emms_c();
    return ret;


static void mpegts_write_pes(AVFormatContext *s, AVStream *st,

                             const uint8_t *payload, int payload_size,

                             int64_t pts, int64_t dts, int key, int stream_id)

{

    MpegTSWriteStream *ts_st = st->priv_data;

    MpegTSWrite *ts = s->priv_data;

    uint8_t buf[TS_PACKET_SIZE];

    uint8_t *q;

    int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, is_dvb_teletext, flags;

    int afc_len, stuffing_len;

    int64_t pcr = -1; /* avoid warning */

    int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);

    int force_pat = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key;

    av_assert0(ts_st->payload != buf || st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO);

    if (ts->flags & MPEGTS_FLAG_PAT_PMT_AT_FRAMES && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {

        force_pat = 1;

    is_start = 1;

    while (payload_size > 0) {

        retransmit_si_info(s, force_pat, dts);

        force_pat = 0;

        write_pcr = 0;

        if (ts_st->pid == ts_st->service->pcr_pid) {

            if (ts->mux_rate > 1 || is_start) // VBR pcr period is based on frames

                ts_st->service->pcr_packet_count++;

            if (ts_st->service->pcr_packet_count >=

                ts_st->service->pcr_packet_period) {

                ts_st->service->pcr_packet_count = 0;

                write_pcr = 1;

        if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE &&

            (dts - get_pcr(ts, s->pb) / 300) > delay) {

            /* pcr insert gets priority over null packet insert */

            if (write_pcr)

                mpegts_insert_pcr_only(s, st);

            else

                mpegts_insert_null_packet(s);

            /* recalculate write_pcr and possibly retransmit si_info */

            continue;

        /* prepare packet header */

        q    = buf;

        *q++ = 0x47;

        val  = ts_st->pid >> 8;

        if (is_start)

            val |= 0x40;

        *q++      = val;

        *q++      = ts_st->pid;

        ts_st->cc = ts_st->cc + 1 & 0xf;

        *q++      = 0x10 | ts_st->cc; // payload indicator + CC

        if (key && is_start && pts != AV_NOPTS_VALUE) {

            // set Random Access for key frames

            if (ts_st->pid == ts_st->service->pcr_pid)

                write_pcr = 1;

            set_af_flag(buf, 0x40);

        if (write_pcr) {

            set_af_flag(buf, 0x10);

            // add 11, pcr references the last byte of program clock reference base

            if (ts->mux_rate > 1)

                pcr = get_pcr(ts, s->pb);

            else

                pcr = (dts - delay) * 300;

            if (dts != AV_NOPTS_VALUE && dts < pcr / 300)

                av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n");

            extend_af(buf, write_pcr_bits(q, pcr));

        if (is_start) {

            int pes_extension = 0;

            int pes_header_stuffing_bytes = 0;

            /* write PES header */

            *q++ = 0x00;

            *q++ = 0x00;

            *q++ = 0x01;

            is_dvb_subtitle = 0;

            is_dvb_teletext = 0;

            if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {

                if (st->codecpar->codec_id == AV_CODEC_ID_DIRAC)

                    *q++ = 0xfd;

                else

                    *q++ = 0xe0;

            } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&

                       (st->codecpar->codec_id == AV_CODEC_ID_MP2 ||

                        st->codecpar->codec_id == AV_CODEC_ID_MP3 ||

                        st->codecpar->codec_id == AV_CODEC_ID_AAC)) {

                *q++ = 0xc0;

            } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&

                        st->codecpar->codec_id == AV_CODEC_ID_AC3 &&

                        ts->m2ts_mode) {

                *q++ = 0xfd;

            } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA &&

                       st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {

                *q++ = 0xbd;

            } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {

                *q++ = stream_id != -1 ? stream_id : 0xfc;

                if (stream_id == 0xbd) /* asynchronous KLV */

                    pts = dts = AV_NOPTS_VALUE;

            } else {

                *q++ = 0xbd;

                if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {

                    if (st->codecpar->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {

                        is_dvb_subtitle = 1;

                    } else if (st->codecpar->codec_id == AV_CODEC_ID_DVB_TELETEXT) {

                        is_dvb_teletext = 1;

            header_len = 0;

            flags      = 0;

            if (pts != AV_NOPTS_VALUE) {

                header_len += 5;

                flags      |= 0x80;

            if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) {

                header_len += 5;

                flags      |= 0x40;

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

                st->codecpar->codec_id == AV_CODEC_ID_DIRAC) {

                /* set PES_extension_flag */

                pes_extension = 1;

                flags        |= 0x01;

                /* One byte for PES2 extension flag +

                 * one byte for extension length +

                 * one byte for extension id */

                header_len += 3;

            /* for Blu-ray AC3 Audio the PES Extension flag should be as follow

             * otherwise it will not play sound on blu-ray

             */

            if (ts->m2ts_mode &&

                st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&

                st->codecpar->codec_id == AV_CODEC_ID_AC3) {

                        /* set PES_extension_flag */

                        pes_extension = 1;

                        flags |= 0x01;

                        header_len += 3;

            if (is_dvb_teletext) {

                pes_header_stuffing_bytes = 0x24 - header_len;

                header_len = 0x24;

            len = payload_size + header_len + 3;

            /* 3 extra bytes should be added to DVB subtitle payload: 0x20 0x00 at the beginning and trailing 0xff */

            if (is_dvb_subtitle) {

                len += 3;

                payload_size++;

            if (len > 0xffff)

                len = 0;

            if (ts->omit_video_pes_length && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {

                len = 0;

            *q++ = len >> 8;

            *q++ = len;

            val  = 0x80;

            /* data alignment indicator is required for subtitle and data streams */

            if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE || st->codecpar->codec_type == AVMEDIA_TYPE_DATA)

                val |= 0x04;

            *q++ = val;

            *q++ = flags;

            *q++ = header_len;

            if (pts != AV_NOPTS_VALUE) {

                write_pts(q, flags >> 6, pts);

                q += 5;

            if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) {

                write_pts(q, 1, dts);

                q += 5;

            if (pes_extension && st->codecpar->codec_id == AV_CODEC_ID_DIRAC) {

                flags = 0x01;  /* set PES_extension_flag_2 */

                *q++  = flags;

                *q++  = 0x80 | 0x01; /* marker bit + extension length */

                /* Set the stream ID extension flag bit to 0 and

                 * write the extended stream ID. */

                *q++ = 0x00 | 0x60;

            /* For Blu-ray AC3 Audio Setting extended flags */

          if (ts->m2ts_mode &&

              pes_extension &&

              st->codecpar->codec_id == AV_CODEC_ID_AC3) {

                      flags = 0x01; /* set PES_extension_flag_2 */

                      *q++ = flags;

                      *q++ = 0x80 | 0x01; /* marker bit + extension length */

                      *q++ = 0x00 | 0x71; /* for AC3 Audio (specifically on blue-rays) */

            if (is_dvb_subtitle) {

                /* First two fields of DVB subtitles PES data:

                 * data_identifier: for DVB subtitle streams shall be coded with the value 0x20

                 * subtitle_stream_id: for DVB subtitle stream shall be identified by the value 0x00 */

                *q++ = 0x20;

                *q++ = 0x00;

            if (is_dvb_teletext) {

                memset(q, 0xff, pes_header_stuffing_bytes);

                q += pes_header_stuffing_bytes;

            is_start = 0;

        /* header size */

        header_len = q - buf;

        /* data len */

        len = TS_PACKET_SIZE - header_len;

        if (len > payload_size)

            len = payload_size;

        stuffing_len = TS_PACKET_SIZE - header_len - len;

        if (stuffing_len > 0) {

            /* add stuffing with AFC */

            if (buf[3] & 0x20) {

                /* stuffing already present: increase its size */

                afc_len = buf[4] + 1;

                memmove(buf + 4 + afc_len + stuffing_len,

                        buf + 4 + afc_len,

                        header_len - (4 + afc_len));

                buf[4] += stuffing_len;

                memset(buf + 4 + afc_len, 0xff, stuffing_len);

            } else {

                /* add stuffing */

                memmove(buf + 4 + stuffing_len, buf + 4, header_len - 4);

                buf[3] |= 0x20;

                buf[4]  = stuffing_len - 1;

                if (stuffing_len >= 2) {

                    buf[5] = 0x00;

                    memset(buf + 6, 0xff, stuffing_len - 2);

        if (is_dvb_subtitle && payload_size == len) {

            memcpy(buf + TS_PACKET_SIZE - len, payload, len - 1);

            buf[TS_PACKET_SIZE - 1] = 0xff; /* end_of_PES_data_field_marker: an 8-bit field with fixed contents 0xff for DVB subtitle */

        } else {

            memcpy(buf + TS_PACKET_SIZE - len, payload, len);

        payload      += len;

        payload_size -= len;

        mpegts_prefix_m2ts_header(s);

        avio_write(s->pb, buf, TS_PACKET_SIZE);

    ts_st->prev_payload_key = key;


void ff_ac3_bit_alloc_calc_bap(int16_t *mask, int16_t *psd, int start, int end,

                               int snr_offset, int floor,

                               const uint8_t *bap_tab, uint8_t *bap)

{

    int i, j, end1, v, address;

    /* special case, if snr offset is -960, set all bap's to zero */

    if (snr_offset == -960) {

        memset(bap, 0, 256);

        return;

    }

    i = start;

    j = bin_to_band_tab[start];

    do {

        v = (FFMAX(mask[j] - snr_offset - floor, 0) & 0x1FE0) + floor;

        end1 = FFMIN(band_start_tab[j] + ff_ac3_critical_band_size_tab[j], end);

        for (; i < end1; i++) {

            address = av_clip((psd[i] - v) >> 5, 0, 63);

            bap[i] = bap_tab[address];

        }

    } while (end > band_start_tab[j++]);

}


static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,

    uint16_t **refcount_table, int64_t *refcount_table_size, int64_t l2_offset,

    int flags)

{

    BDRVQcowState *s = bs->opaque;

    uint64_t *l2_table, l2_entry;

    uint64_t next_contiguous_offset = 0;

    int i, l2_size, nb_csectors, ret;

    /* Read L2 table from disk */

    l2_size = s->l2_size * sizeof(uint64_t);

    l2_table = g_malloc(l2_size);

    ret = bdrv_pread(bs->file, l2_offset, l2_table, l2_size);

    if (ret < 0) {

        fprintf(stderr, "ERROR: I/O error in check_refcounts_l2\n");

        res->check_errors++;

        goto fail;

    }

    /* Do the actual checks */

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

        l2_entry = be64_to_cpu(l2_table[i]);

        switch (qcow2_get_cluster_type(l2_entry)) {

        case QCOW2_CLUSTER_COMPRESSED:

            /* Compressed clusters don't have QCOW_OFLAG_COPIED */

            if (l2_entry & QCOW_OFLAG_COPIED) {

                fprintf(stderr, "ERROR: cluster %" PRId64 ": "

                    "copied flag must never be set for compressed "

                    "clusters\n", l2_entry >> s->cluster_bits);

                l2_entry &= ~QCOW_OFLAG_COPIED;

                res->corruptions++;

            }

            /* Mark cluster as used */

            nb_csectors = ((l2_entry >> s->csize_shift) &

                           s->csize_mask) + 1;

            l2_entry &= s->cluster_offset_mask;

            ret = inc_refcounts(bs, res, refcount_table, refcount_table_size,

                                l2_entry & ~511, nb_csectors * 512);

            if (ret < 0) {

                goto fail;

            }

            if (flags & CHECK_FRAG_INFO) {

                res->bfi.allocated_clusters++;

                res->bfi.compressed_clusters++;

                /* Compressed clusters are fragmented by nature.  Since they

                 * take up sub-sector space but we only have sector granularity

                 * I/O we need to re-read the same sectors even for adjacent

                 * compressed clusters.

                 */

                res->bfi.fragmented_clusters++;

            }

            break;

        case QCOW2_CLUSTER_ZERO:

            if ((l2_entry & L2E_OFFSET_MASK) == 0) {

                break;

            }

            /* fall through */

        case QCOW2_CLUSTER_NORMAL:

        {

            uint64_t offset = l2_entry & L2E_OFFSET_MASK;

            if (flags & CHECK_FRAG_INFO) {

                res->bfi.allocated_clusters++;

                if (next_contiguous_offset &&

                    offset != next_contiguous_offset) {

                    res->bfi.fragmented_clusters++;

                }

                next_contiguous_offset = offset + s->cluster_size;

            }

            /* Mark cluster as used */

            ret = inc_refcounts(bs, res, refcount_table, refcount_table_size,

                                offset, s->cluster_size);

            if (ret < 0) {

                goto fail;

            }

            /* Correct offsets are cluster aligned */

            if (offset_into_cluster(s, offset)) {

                fprintf(stderr, "ERROR offset=%" PRIx64 ": Cluster is not "

                    "properly aligned; L2 entry corrupted.\n", offset);

                res->corruptions++;

            }

            break;

        }

        case QCOW2_CLUSTER_UNALLOCATED:

            break;

        default:

            abort();

        }

    }

    g_free(l2_table);

    return 0;

fail:

    g_free(l2_table);

    return ret;

}


static inline void mix_3f_to_mono(AC3DecodeContext *ctx)

{

    int i;

    float (*output)[256] = ctx->audio_block.block_output;

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

        output[1][i] += (output[2][i] + output[3][i]);

    memset(output[2], 0, sizeof(output[2]));

    memset(output[3], 0, sizeof(output[3]));

}


int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)

{

    int pqindex, lowquant;

    int status;

    int mbmodetab, imvtab, icbptab, twomvbptab, fourmvbptab; /* useful only for debugging */

    int scale, shift, i; /* for initializing LUT for intensity compensation */

    v->numref=0;

    v->p_frame_skipped = 0;

    if (v->second_field) {

        if(v->fcm!=2 || v->field_mode!=1)

            return -1;

        v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;

        if (v->fptype & 4)

            v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B;

        v->s.current_picture_ptr->f.pict_type = v->s.pict_type;

        if (!v->pic_header_flag)

            goto parse_common_info;

    }

    v->field_mode = 0;

    if (v->interlace) {

        v->fcm = decode012(gb);

        if (v->fcm) {

            if (v->fcm == ILACE_FIELD)

                v->field_mode = 1;

            if (!v->warn_interlaced++)

                av_log(v->s.avctx, AV_LOG_ERROR,

                       "Interlaced frames/fields support is incomplete\n");

        }

    } else {

        v->fcm = PROGRESSIVE;

    }

    if (v->field_mode) {

        v->fptype = get_bits(gb, 3);

        v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;

        if (v->fptype & 4) // B-picture

            v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B;

    } else {

        switch (get_unary(gb, 0, 4)) {

        case 0:

            v->s.pict_type = AV_PICTURE_TYPE_P;

            break;

        case 1:

            v->s.pict_type = AV_PICTURE_TYPE_B;

            break;

        case 2:

            v->s.pict_type = AV_PICTURE_TYPE_I;

            break;

        case 3:

            v->s.pict_type = AV_PICTURE_TYPE_BI;

            break;

        case 4:

            v->s.pict_type = AV_PICTURE_TYPE_P; // skipped pic

            v->p_frame_skipped = 1;

            break;

        }

    }

    if (v->tfcntrflag)

        skip_bits(gb, 8);

    if (v->broadcast) {

        if (!v->interlace || v->psf) {

            v->rptfrm = get_bits(gb, 2);

        } else {

            v->tff = get_bits1(gb);

            v->rff = get_bits1(gb);

        }

    }

    if (v->panscanflag) {

        av_log_missing_feature(v->s.avctx, "Pan-scan", 0);

        //...

    }

    if (v->p_frame_skipped) {

        return 0;

    }

    v->rnd = get_bits1(gb);

    if (v->interlace)

        v->uvsamp = get_bits1(gb);

    if(!ff_vc1_bfraction_vlc.table)

        return 0; //parsing only, vlc tables havnt been allocated

    if (v->field_mode) {

        if (!v->refdist_flag)

            v->refdist = 0;

        else if ((v->s.pict_type != AV_PICTURE_TYPE_B) && (v->s.pict_type != AV_PICTURE_TYPE_BI)) {

            v->refdist = get_bits(gb, 2);

            if (v->refdist == 3)

                v->refdist += get_unary(gb, 0, 16);

        }

        if ((v->s.pict_type == AV_PICTURE_TYPE_B) || (v->s.pict_type == AV_PICTURE_TYPE_BI)) {

            v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1);

            v->bfraction           = ff_vc1_bfraction_lut[v->bfraction_lut_index];

            v->frfd = (v->bfraction * v->refdist) >> 8;

            v->brfd = v->refdist - v->frfd - 1;

            if (v->brfd < 0)

                v->brfd = 0;

        }

        goto parse_common_info;

    }

    if (v->fcm == PROGRESSIVE) {

        if (v->finterpflag)

            v->interpfrm = get_bits1(gb);

        if (v->s.pict_type == AV_PICTURE_TYPE_B) {

            v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1);

            v->bfraction           = ff_vc1_bfraction_lut[v->bfraction_lut_index];

            if (v->bfraction == 0) {

                v->s.pict_type = AV_PICTURE_TYPE_BI; /* XXX: should not happen here */

            }

        }

    }

    parse_common_info:

    if (v->field_mode)

        v->cur_field_type = !(v->tff ^ v->second_field);

    pqindex = get_bits(gb, 5);

    if (!pqindex)

        return -1;

    v->pqindex = pqindex;

    if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)

        v->pq = ff_vc1_pquant_table[0][pqindex];

    else

        v->pq = ff_vc1_pquant_table[1][pqindex];

    v->pquantizer = 1;

    if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)

        v->pquantizer = pqindex < 9;

    if (v->quantizer_mode == QUANT_NON_UNIFORM)

        v->pquantizer = 0;

    v->pqindex = pqindex;

    if (pqindex < 9)

        v->halfpq = get_bits1(gb);

    else

        v->halfpq = 0;

    if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)

        v->pquantizer = get_bits1(gb);

    if (v->postprocflag)

        v->postproc = get_bits(gb, 2);

    if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P)

        v->use_ic = 0;

    if (v->parse_only)

        return 0;

    switch (v->s.pict_type) {

    case AV_PICTURE_TYPE_I:

    case AV_PICTURE_TYPE_BI:

        if (v->fcm == ILACE_FRAME) { //interlace frame picture

            status = bitplane_decoding(v->fieldtx_plane, &v->fieldtx_is_raw, v);

            if (status < 0)

                return -1;

            av_log(v->s.avctx, AV_LOG_DEBUG, "FIELDTX plane encoding: "

                   "Imode: %i, Invert: %i\n", status>>1, status&1);

        }

        status = bitplane_decoding(v->acpred_plane, &v->acpred_is_raw, v);

        if (status < 0)

            return -1;

        av_log(v->s.avctx, AV_LOG_DEBUG, "ACPRED plane encoding: "

               "Imode: %i, Invert: %i\n", status>>1, status&1);

        v->condover = CONDOVER_NONE;

        if (v->overlap && v->pq <= 8) {

            v->condover = decode012(gb);

            if (v->condover == CONDOVER_SELECT) {

                status = bitplane_decoding(v->over_flags_plane, &v->overflg_is_raw, v);

                if (status < 0)

                    return -1;

                av_log(v->s.avctx, AV_LOG_DEBUG, "CONDOVER plane encoding: "

                       "Imode: %i, Invert: %i\n", status>>1, status&1);

            }

        }

        break;

    case AV_PICTURE_TYPE_P:

        if (v->field_mode) {

            v->numref = get_bits1(gb);

            if (!v->numref) {

                v->reffield          = get_bits1(gb);

                v->ref_field_type[0] = v->reffield ^ !v->cur_field_type;

            }

        }

        if (v->extended_mv)

            v->mvrange = get_unary(gb, 0, 3);

        else

            v->mvrange = 0;

        if (v->interlace) {

            if (v->extended_dmv)

                v->dmvrange = get_unary(gb, 0, 3);

            else

                v->dmvrange = 0;

            if (v->fcm == ILACE_FRAME) { // interlaced frame picture

                v->fourmvswitch = get_bits1(gb);

                v->intcomp      = get_bits1(gb);

                if (v->intcomp) {

                    v->lumscale = get_bits(gb, 6);

                    v->lumshift = get_bits(gb, 6);

                    INIT_LUT(v->lumscale, v->lumshift, v->luty, v->lutuv);

                }

                status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);

                av_log(v->s.avctx, AV_LOG_DEBUG, "SKIPMB plane encoding: "

                       "Imode: %i, Invert: %i\n", status>>1, status&1);

                mbmodetab = get_bits(gb, 2);

                if (v->fourmvswitch)

                    v->mbmode_vlc = &ff_vc1_intfr_4mv_mbmode_vlc[mbmodetab];

                else

                    v->mbmode_vlc = &ff_vc1_intfr_non4mv_mbmode_vlc[mbmodetab];

                imvtab         = get_bits(gb, 2);

                v->imv_vlc     = &ff_vc1_1ref_mvdata_vlc[imvtab];

                // interlaced p-picture cbpcy range is [1, 63]

                icbptab        = get_bits(gb, 3);

                v->cbpcy_vlc   = &ff_vc1_icbpcy_vlc[icbptab];

                twomvbptab     = get_bits(gb, 2);

                v->twomvbp_vlc = &ff_vc1_2mv_block_pattern_vlc[twomvbptab];

                if (v->fourmvswitch) {

                    fourmvbptab     = get_bits(gb, 2);

                    v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab];

                }

            }

        }

        v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13

        v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11

        v->range_x = 1 << (v->k_x - 1);

        v->range_y = 1 << (v->k_y - 1);

        if (v->pq < 5)

            v->tt_index = 0;

        else if (v->pq < 13)

            v->tt_index = 1;

        else

            v->tt_index = 2;

        if (v->fcm != ILACE_FRAME) {

            int mvmode;

            mvmode     = get_unary(gb, 1, 4);

            lowquant   = (v->pq > 12) ? 0 : 1;

            v->mv_mode = ff_vc1_mv_pmode_table[lowquant][mvmode];

            if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {

                int mvmode2;

                mvmode2 = get_unary(gb, 1, 3);

                v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][mvmode2];

                if (v->field_mode)

                    v->intcompfield = decode210(gb);

                v->lumscale = get_bits(gb, 6);

                v->lumshift = get_bits(gb, 6);

                INIT_LUT(v->lumscale, v->lumshift, v->luty, v->lutuv);

                if ((v->field_mode) && !v->intcompfield) {

                    v->lumscale2 = get_bits(gb, 6);

                    v->lumshift2 = get_bits(gb, 6);

                    INIT_LUT(v->lumscale2, v->lumshift2, v->luty2, v->lutuv2);

                }

                v->use_ic = 1;

            }

            v->qs_last = v->s.quarter_sample;

            if (v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)

                v->s.quarter_sample = 0;

            else if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {

                if (v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)

                    v->s.quarter_sample = 0;

                else

                    v->s.quarter_sample = 1;

            } else

                v->s.quarter_sample = 1;

            v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN

                           || (v->mv_mode == MV_PMODE_INTENSITY_COMP

                               && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN));

        }

        if (v->fcm == PROGRESSIVE) { // progressive

            if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&

                 v->mv_mode2 == MV_PMODE_MIXED_MV)

                || v->mv_mode == MV_PMODE_MIXED_MV) {

                status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v);

                if (status < 0)

                    return -1;

                av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "

                       "Imode: %i, Invert: %i\n", status>>1, status&1);

            } else {

                v->mv_type_is_raw = 0;

                memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height);

            }

            status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);

            if (status < 0)

                return -1;

            av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "

                   "Imode: %i, Invert: %i\n", status>>1, status&1);

            /* Hopefully this is correct for P frames */

            v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables

            v->cbpcy_vlc        = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];

        } else if (v->fcm == ILACE_FRAME) { // frame interlaced

            v->qs_last          = v->s.quarter_sample;

            v->s.quarter_sample = 1;

            v->s.mspel          = 1;

        } else {    // field interlaced

            mbmodetab = get_bits(gb, 3);

            imvtab = get_bits(gb, 2 + v->numref);

            if (!v->numref)

                v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab];

            else

                v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[imvtab];

            icbptab = get_bits(gb, 3);

            v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab];

            if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&

                v->mv_mode2 == MV_PMODE_MIXED_MV) || v->mv_mode == MV_PMODE_MIXED_MV) {

                fourmvbptab     = get_bits(gb, 2);

                v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab];

                v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[mbmodetab];

            } else {

                v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[mbmodetab];

            }

        }

        if (v->dquant) {

            av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");

            vop_dquant_decoding(v);

        }

        v->ttfrm = 0; //FIXME Is that so ?

        if (v->vstransform) {

            v->ttmbf = get_bits1(gb);

            if (v->ttmbf) {

                v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)];

            }

        } else {

            v->ttmbf = 1;

            v->ttfrm = TT_8X8;

        }

        break;

    case AV_PICTURE_TYPE_B:

        if (v->fcm == ILACE_FRAME) {

            v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1);

            v->bfraction           = ff_vc1_bfraction_lut[v->bfraction_lut_index];

            if (v->bfraction == 0) {

                return -1;

            }

        }

        if (v->extended_mv)

            v->mvrange = get_unary(gb, 0, 3);

        else

            v->mvrange = 0;

        v->k_x     = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13

        v->k_y     = v->mvrange + 8; //k_y can be 8 9 10 11

        v->range_x = 1 << (v->k_x - 1);

        v->range_y = 1 << (v->k_y - 1);

        if (v->pq < 5)

            v->tt_index = 0;

        else if (v->pq < 13)

            v->tt_index = 1;

        else

            v->tt_index = 2;

        if (v->field_mode) {

            int mvmode;

            av_log(v->s.avctx, AV_LOG_DEBUG, "B Fields\n");

            if (v->extended_dmv)

                v->dmvrange = get_unary(gb, 0, 3);

            mvmode = get_unary(gb, 1, 3);

            lowquant = (v->pq > 12) ? 0 : 1;

            v->mv_mode          = ff_vc1_mv_pmode_table2[lowquant][mvmode];

            v->qs_last          = v->s.quarter_sample;

            v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV || v->mv_mode == MV_PMODE_MIXED_MV);

            v->s.mspel          = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || v->mv_mode == MV_PMODE_1MV_HPEL);

            status = bitplane_decoding(v->forward_mb_plane, &v->fmb_is_raw, v);

            if (status < 0)

                return -1;

            av_log(v->s.avctx, AV_LOG_DEBUG, "MB Forward Type plane encoding: "

                   "Imode: %i, Invert: %i\n", status>>1, status&1);

            mbmodetab = get_bits(gb, 3);

            if (v->mv_mode == MV_PMODE_MIXED_MV)

                v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[mbmodetab];

            else

                v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[mbmodetab];

            imvtab       = get_bits(gb, 3);

            v->imv_vlc   = &ff_vc1_2ref_mvdata_vlc[imvtab];

            icbptab      = get_bits(gb, 3);

            v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab];

            if (v->mv_mode == MV_PMODE_MIXED_MV) {

                fourmvbptab     = get_bits(gb, 2);

                v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab];

            }

            v->numref = 1; // interlaced field B pictures are always 2-ref

        } else if (v->fcm == ILACE_FRAME) {

            if (v->extended_dmv)

                v->dmvrange = get_unary(gb, 0, 3);

            get_bits1(gb); /* intcomp - present but shall always be 0 */

            v->intcomp          = 0;

            v->mv_mode          = MV_PMODE_1MV;

            v->fourmvswitch     = 0;

            v->qs_last          = v->s.quarter_sample;

            v->s.quarter_sample = 1;

            v->s.mspel          = 1;

            status              = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v);

            if (status < 0)

                return -1;

            av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: "

                   "Imode: %i, Invert: %i\n", status>>1, status&1);

            status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);

            if (status < 0)

                return -1;

            av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "

                   "Imode: %i, Invert: %i\n", status>>1, status&1);

            mbmodetab       = get_bits(gb, 2);

            v->mbmode_vlc   = &ff_vc1_intfr_non4mv_mbmode_vlc[mbmodetab];

            imvtab          = get_bits(gb, 2);

            v->imv_vlc      = &ff_vc1_1ref_mvdata_vlc[imvtab];

            // interlaced p/b-picture cbpcy range is [1, 63]

            icbptab         = get_bits(gb, 3);

            v->cbpcy_vlc    = &ff_vc1_icbpcy_vlc[icbptab];

            twomvbptab      = get_bits(gb, 2);

            v->twomvbp_vlc  = &ff_vc1_2mv_block_pattern_vlc[twomvbptab];

            fourmvbptab     = get_bits(gb, 2);

            v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab];

        } else {

            v->mv_mode          = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;

            v->qs_last          = v->s.quarter_sample;

            v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV);

            v->s.mspel          = v->s.quarter_sample;

            status              = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v);

            if (status < 0)

                return -1;

            av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: "

                   "Imode: %i, Invert: %i\n", status>>1, status&1);

            status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);

            if (status < 0)

                return -1;

            av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "

                   "Imode: %i, Invert: %i\n", status>>1, status&1);

            v->s.mv_table_index = get_bits(gb, 2);

            v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];

        }

        if (v->dquant) {

            av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");

            vop_dquant_decoding(v);

        }

        v->ttfrm = 0;

        if (v->vstransform) {

            v->ttmbf = get_bits1(gb);

            if (v->ttmbf) {

                v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)];

            }

        } else {

            v->ttmbf = 1;

            v->ttfrm = TT_8X8;

        }

        break;

    }

    if (v->fcm != PROGRESSIVE && !v->s.quarter_sample) {

        v->range_x <<= 1;

        v->range_y <<= 1;

    }

    /* AC Syntax */

    v->c_ac_table_index = decode012(gb);

    if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) {

        v->y_ac_table_index = decode012(gb);

    }

    /* DC Syntax */

    v->s.dc_table_index = get_bits1(gb);

    if ((v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)

        && v->dquant) {

        av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");

        vop_dquant_decoding(v);

    }

    v->bi_type = 0;

    if (v->s.pict_type == AV_PICTURE_TYPE_BI) {

        v->s.pict_type = AV_PICTURE_TYPE_B;

        v->bi_type = 1;

    }

    return 0;

}


static int vivo_probe(AVProbeData *p)

{

    const unsigned char *buf = p->buf;

    unsigned c, length = 0;

    // stream must start with packet of type 0 and sequence number 0

    if (*buf++ != 0)

        return 0;

    // read at most 2 bytes of coded length

    c = *buf++;

    length = c & 0x7F;

    if (c & 0x80) {

        c = *buf++;

        length = (length << 7) | (c & 0x7F);

    }

    if (c & 0x80 || length > 1024 || length < 21)

        return 0;

    if (memcmp(buf, "\r\nVersion:Vivo/", 15))

        return 0;

    buf += 15;

    if (*buf < '0' && *buf > '2')

        return 0;

    return AVPROBE_SCORE_MAX;

}


static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time)

{

    char buf[1024];

    AVBPrint buf_script;

    OutputStream *ost;

    AVFormatContext *oc;

    int64_t total_size;

    AVCodecContext *enc;

    int frame_number, vid, i;

    double bitrate;

    int64_t pts = INT64_MIN;

    static int64_t last_time = -1;

    static int qp_histogram[52];

    int hours, mins, secs, us;

    if (!print_stats && !is_last_report && !progress_avio)

        return;

    if (!is_last_report) {

        if (last_time == -1) {

            last_time = cur_time;

            return;

        }

        if ((cur_time - last_time) < 500000)

            return;

        last_time = cur_time;

    }

    oc = output_files[0]->ctx;

    total_size = avio_size(oc->pb);

    if (total_size <= 0) // FIXME improve avio_size() so it works with non seekable output too

        total_size = avio_tell(oc->pb);

    buf[0] = '\0';

    vid = 0;

    av_bprint_init(&buf_script, 0, 1);

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

        float q = -1;

        ost = output_streams[i];

        enc = ost->enc_ctx;

        if (!ost->stream_copy && enc->coded_frame)

            q = enc->coded_frame->quality / (float)FF_QP2LAMBDA;

        if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {

            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q);

            av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",

                       ost->file_index, ost->index, q);

        }

        if (!vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {

            float fps, t = (cur_time-timer_start) / 1000000.0;

            frame_number = ost->frame_number;

            fps = t > 1 ? frame_number / t : 0;

            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3.*f q=%3.1f ",

                     frame_number, fps < 9.95, fps, q);

            av_bprintf(&buf_script, "frame=%d\n", frame_number);

            av_bprintf(&buf_script, "fps=%.1f\n", fps);

            av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",

                       ost->file_index, ost->index, q);

            if (is_last_report)

                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L");

            if (qp_hist) {

                int j;

                int qp = lrintf(q);

                if (qp >= 0 && qp < FF_ARRAY_ELEMS(qp_histogram))

                    qp_histogram[qp]++;

                for (j = 0; j < 32; j++)

                    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%X", (int)lrintf(log2(qp_histogram[j] + 1)));

            }

            if ((enc->flags&CODEC_FLAG_PSNR) && (enc->coded_frame || is_last_report)) {

                int j;

                double error, error_sum = 0;

                double scale, scale_sum = 0;

                double p;

                char type[3] = { 'Y','U','V' };

                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "PSNR=");

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

                    if (is_last_report) {

                        error = enc->error[j];

                        scale = enc->width * enc->height * 255.0 * 255.0 * frame_number;

                    } else {

                        error = enc->coded_frame->error[j];

                        scale = enc->width * enc->height * 255.0 * 255.0;

                    }

                    if (j)

                        scale /= 4;

                    error_sum += error;

                    scale_sum += scale;

                    p = psnr(error / scale);

                    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c:%2.2f ", type[j], p);

                    av_bprintf(&buf_script, "stream_%d_%d_psnr_%c=%2.2f\n",

                               ost->file_index, ost->index, type[j] | 32, p);

                }

                p = psnr(error_sum / scale_sum);

                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "*:%2.2f ", psnr(error_sum / scale_sum));

                av_bprintf(&buf_script, "stream_%d_%d_psnr_all=%2.2f\n",

                           ost->file_index, ost->index, p);

            }

            vid = 1;

        }

        /* compute min output value */

        if (av_stream_get_end_pts(ost->st) != AV_NOPTS_VALUE)

            pts = FFMAX(pts, av_rescale_q(av_stream_get_end_pts(ost->st),

                                          ost->st->time_base, AV_TIME_BASE_Q));

        if (is_last_report)

            nb_frames_drop += ost->last_droped;

    }

    secs = pts / AV_TIME_BASE;

    us = pts % AV_TIME_BASE;

    mins = secs / 60;

    secs %= 60;

    hours = mins / 60;

    mins %= 60;

    bitrate = pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;

    if (total_size < 0) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),

                                 "size=N/A time=");

    else                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),

                                 "size=%8.0fkB time=", total_size / 1024.0);

    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),

             "%02d:%02d:%02d.%02d ", hours, mins, secs,

             (100 * us) / AV_TIME_BASE);

    if (bitrate < 0) {

        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),"bitrate=N/A");

        av_bprintf(&buf_script, "bitrate=N/A\n");

    }else{

        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),"bitrate=%6.1fkbits/s", bitrate);

        av_bprintf(&buf_script, "bitrate=%6.1fkbits/s\n", bitrate);

    }

    if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");

    else                av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);

    av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);

    av_bprintf(&buf_script, "out_time=%02d:%02d:%02d.%06d\n",

               hours, mins, secs, us);

    if (nb_frames_dup || nb_frames_drop)

        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d",

                nb_frames_dup, nb_frames_drop);

    av_bprintf(&buf_script, "dup_frames=%d\n", nb_frames_dup);

    av_bprintf(&buf_script, "drop_frames=%d\n", nb_frames_drop);

    if (print_stats || is_last_report) {

        const char end = is_last_report ? '\n' : '\r';

        if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) {

            fprintf(stderr, "%s    %c", buf, end);

        } else

            av_log(NULL, AV_LOG_INFO, "%s    %c", buf, end);

    fflush(stderr);

    }

    if (progress_avio) {

        av_bprintf(&buf_script, "progress=%s\n",

                   is_last_report ? "end" : "continue");

        avio_write(progress_avio, buf_script.str,

                   FFMIN(buf_script.len, buf_script.size - 1));

        avio_flush(progress_avio);

        av_bprint_finalize(&buf_script, NULL);

        if (is_last_report) {

            avio_closep(&progress_avio);

        }

    }

    if (is_last_report)

        print_final_stats(total_size);

}


static int put_packetheader(NUTContext *nut, ByteIOContext *bc, int max_size)

{

    put_flush_packet(bc);

    nut->last_packet_start= nut->packet_start;

    nut->packet_start+= nut->written_packet_size;

    nut->packet_size_pos = url_ftell(bc);

    nut->written_packet_size = max_size;

    /* packet header */

    put_v(bc, nut->written_packet_size); /* forward ptr */

    put_v(bc, nut->packet_start - nut->last_packet_start); /* backward ptr */

    return 0;

}


static int decode_mb_cavlc(H264Context *h){

    MpegEncContext * const s = &h->s;

    int mb_xy;

    int partition_count;

    unsigned int mb_type, cbp;

    int dct8x8_allowed= h->pps.transform_8x8_mode;

    mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride;

    s->dsp.clear_blocks(h->mb); //FIXME avoid if already clear (move after skip handlong?

    tprintf(s->avctx, "pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y);

    cbp = 0; /* avoid warning. FIXME: find a solution without slowing

                down the code */

    if(h->slice_type_nos != FF_I_TYPE){

        if(s->mb_skip_run==-1)

            s->mb_skip_run= get_ue_golomb(&s->gb);

        if (s->mb_skip_run--) {

            if(FRAME_MBAFF && (s->mb_y&1) == 0){

                if(s->mb_skip_run==0)

                    h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&s->gb);

                else

                    predict_field_decoding_flag(h);

            }

            decode_mb_skip(h);

            return 0;

        }

    }

    if(FRAME_MBAFF){

        if( (s->mb_y&1) == 0 )

            h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&s->gb);

    }else

        h->mb_field_decoding_flag= (s->picture_structure!=PICT_FRAME);

    h->prev_mb_skipped= 0;

    mb_type= get_ue_golomb(&s->gb);

    if(h->slice_type_nos == FF_B_TYPE){

        if(mb_type < 23){

            partition_count= b_mb_type_info[mb_type].partition_count;

            mb_type=         b_mb_type_info[mb_type].type;

        }else{

            mb_type -= 23;

            goto decode_intra_mb;

        }

    }else if(h->slice_type_nos == FF_P_TYPE){

        if(mb_type < 5){

            partition_count= p_mb_type_info[mb_type].partition_count;

            mb_type=         p_mb_type_info[mb_type].type;

        }else{

            mb_type -= 5;

            goto decode_intra_mb;

        }

    }else{

       assert(h->slice_type_nos == FF_I_TYPE);

        if(h->slice_type == FF_SI_TYPE && mb_type)

            mb_type--;

decode_intra_mb:

        if(mb_type > 25){

            av_log(h->s.avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_pict_type_char(h->slice_type), s->mb_x, s->mb_y);

            return -1;

        }

        partition_count=0;

        cbp= i_mb_type_info[mb_type].cbp;

        h->intra16x16_pred_mode= i_mb_type_info[mb_type].pred_mode;

        mb_type= i_mb_type_info[mb_type].type;

    }

    if(MB_FIELD)

        mb_type |= MB_TYPE_INTERLACED;

    h->slice_table[ mb_xy ]= h->slice_num;

    if(IS_INTRA_PCM(mb_type)){

        unsigned int x, y;

        // We assume these blocks are very rare so we do not optimize it.

        align_get_bits(&s->gb);

        // The pixels are stored in the same order as levels in h->mb array.

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

            const int index= 4*(y&3) + 32*((y>>2)&1) + 128*(y>>3);

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

                tprintf(s->avctx, "LUMA ICPM LEVEL (%3d)\n", show_bits(&s->gb, 8));

                h->mb[index + (x&3) + 16*((x>>2)&1) + 64*(x>>3)]= get_bits(&s->gb, 8);

            }

        }

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

            const int index= 256 + 4*(y&3) + 32*(y>>2);

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

                tprintf(s->avctx, "CHROMA U ICPM LEVEL (%3d)\n", show_bits(&s->gb, 8));

                h->mb[index + (x&3) + 16*(x>>2)]= get_bits(&s->gb, 8);

            }

        }

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

            const int index= 256 + 64 + 4*(y&3) + 32*(y>>2);

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

                tprintf(s->avctx, "CHROMA V ICPM LEVEL (%3d)\n", show_bits(&s->gb, 8));

                h->mb[index + (x&3) + 16*(x>>2)]= get_bits(&s->gb, 8);

            }

        }

        // In deblocking, the quantizer is 0

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

        // All coeffs are present

        memset(h->non_zero_count[mb_xy], 16, 16);

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

        return 0;

    }

    if(MB_MBAFF){

        h->ref_count[0] <<= 1;

        h->ref_count[1] <<= 1;

    }

    fill_caches(h, mb_type, 0);

    //mb_pred

    if(IS_INTRA(mb_type)){

            int pred_mode;

//            init_top_left_availability(h);

            if(IS_INTRA4x4(mb_type)){

                int i;

                int di = 1;

                if(dct8x8_allowed && get_bits1(&s->gb)){

                    mb_type |= MB_TYPE_8x8DCT;

                    di = 4;

                }

//                fill_intra4x4_pred_table(h);

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

                    int mode= pred_intra_mode(h, i);

                    if(!get_bits1(&s->gb)){

                        const int rem_mode= get_bits(&s->gb, 3);

                        mode = rem_mode + (rem_mode >= mode);

                    }

                    if(di==4)

                        fill_rectangle( &h->intra4x4_pred_mode_cache[ scan8[i] ], 2, 2, 8, mode, 1 );

                    else

                        h->intra4x4_pred_mode_cache[ scan8[i] ] = mode;

                }

                write_back_intra_pred_mode(h);

                if( check_intra4x4_pred_mode(h) < 0)

                    return -1;

            }else{

                h->intra16x16_pred_mode= check_intra_pred_mode(h, h->intra16x16_pred_mode);

                if(h->intra16x16_pred_mode < 0)

                    return -1;

            }

            pred_mode= check_intra_pred_mode(h, get_ue_golomb(&s->gb));

            if(pred_mode < 0)

                return -1;

            h->chroma_pred_mode= pred_mode;

    }else if(partition_count==4){

        int i, j, sub_partition_count[4], list, ref[2][4];

        if(h->slice_type_nos == FF_B_TYPE){

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

                h->sub_mb_type[i]= get_ue_golomb(&s->gb);

                if(h->sub_mb_type[i] >=13){

                    av_log(h->s.avctx, AV_LOG_ERROR, "B sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], s->mb_x, s->mb_y);

                    return -1;

                }

                sub_partition_count[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;

                h->sub_mb_type[i]=      b_sub_mb_type_info[ h->sub_mb_type[i] ].type;

            }

            if(   IS_DIRECT(h->sub_mb_type[0]) || IS_DIRECT(h->sub_mb_type[1])

               || IS_DIRECT(h->sub_mb_type[2]) || IS_DIRECT(h->sub_mb_type[3])) {

                pred_direct_motion(h, &mb_type);

                h->ref_cache[0][scan8[4]] =

                h->ref_cache[1][scan8[4]] =

                h->ref_cache[0][scan8[12]] =

                h->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;

            }

        }else{

            assert(h->slice_type_nos == FF_P_TYPE); //FIXME SP correct ?

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

                h->sub_mb_type[i]= get_ue_golomb(&s->gb);

                if(h->sub_mb_type[i] >=4){

                    av_log(h->s.avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], s->mb_x, s->mb_y);

                    return -1;

                }

                sub_partition_count[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;

                h->sub_mb_type[i]=      p_sub_mb_type_info[ h->sub_mb_type[i] ].type;

            }

        }

        for(list=0; list<h->list_count; list++){

            int ref_count= IS_REF0(mb_type) ? 1 : h->ref_count[list];

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

                if(IS_DIRECT(h->sub_mb_type[i])) continue;

                if(IS_DIR(h->sub_mb_type[i], 0, list)){

                    unsigned int tmp = get_te0_golomb(&s->gb, ref_count); //FIXME init to 0 before and skip?

                    if(tmp>=ref_count){

                        av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp);

                        return -1;

                    }

                    ref[list][i]= tmp;

                }else{

                 //FIXME

                    ref[list][i] = -1;

                }

            }

        }

        if(dct8x8_allowed)

            dct8x8_allowed = get_dct8x8_allowed(h);

        for(list=0; list<h->list_count; list++){

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

                if(IS_DIRECT(h->sub_mb_type[i])) {

                    h->ref_cache[list][ scan8[4*i] ] = h->ref_cache[list][ scan8[4*i]+1 ];

                    continue;

                }

                h->ref_cache[list][ scan8[4*i]   ]=h->ref_cache[list][ scan8[4*i]+1 ]=

                h->ref_cache[list][ scan8[4*i]+8 ]=h->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i];

                if(IS_DIR(h->sub_mb_type[i], 0, list)){

                    const int sub_mb_type= h->sub_mb_type[i];

                    const int block_width= (sub_mb_type & (MB_TYPE_16x16|MB_TYPE_16x8)) ? 2 : 1;

                    for(j=0; j<sub_partition_count[i]; j++){

                        int mx, my;

                        const int index= 4*i + block_width*j;

                        int16_t (* mv_cache)[2]= &h->mv_cache[list][ scan8[index] ];

                        pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mx, &my);

                        mx += get_se_golomb(&s->gb);

                        my += get_se_golomb(&s->gb);

                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                        if(IS_SUB_8X8(sub_mb_type)){

                            mv_cache[ 1 ][0]=

                            mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx;

                            mv_cache[ 1 ][1]=

                            mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my;

                        }else if(IS_SUB_8X4(sub_mb_type)){

                            mv_cache[ 1 ][0]= mx;

                            mv_cache[ 1 ][1]= my;

                        }else if(IS_SUB_4X8(sub_mb_type)){

                            mv_cache[ 8 ][0]= mx;

                            mv_cache[ 8 ][1]= my;

                        }

                        mv_cache[ 0 ][0]= mx;

                        mv_cache[ 0 ][1]= my;

                    }

                }else{

                    uint32_t *p= (uint32_t *)&h->mv_cache[list][ scan8[4*i] ][0];

                    p[0] = p[1]=

                    p[8] = p[9]= 0;

                }

            }

        }

    }else if(IS_DIRECT(mb_type)){

        pred_direct_motion(h, &mb_type);

        dct8x8_allowed &= h->sps.direct_8x8_inference_flag;

    }else{

        int list, mx, my, i;

         //FIXME we should set ref_idx_l? to 0 if we use that later ...

        if(IS_16X16(mb_type)){

            for(list=0; list<h->list_count; list++){

                    unsigned int val;

                    if(IS_DIR(mb_type, 0, list)){

                        val= get_te0_golomb(&s->gb, h->ref_count[list]);

                        if(val >= h->ref_count[list]){

                            av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);

                            return -1;

                        }

                    }else

                        val= LIST_NOT_USED&0xFF;

                    fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, val, 1);

            }

            for(list=0; list<h->list_count; list++){

                unsigned int val;

                if(IS_DIR(mb_type, 0, list)){

                    pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my);

                    mx += get_se_golomb(&s->gb);

                    my += get_se_golomb(&s->gb);

                    tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                    val= pack16to32(mx,my);

                }else

                    val=0;

                fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, val, 4);

            }

        }

        else if(IS_16X8(mb_type)){

            for(list=0; list<h->list_count; list++){

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

                        unsigned int val;

                        if(IS_DIR(mb_type, i, list)){

                            val= get_te0_golomb(&s->gb, h->ref_count[list]);

                            if(val >= h->ref_count[list]){

                                av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);

                                return -1;

                            }

                        }else

                            val= LIST_NOT_USED&0xFF;

                        fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 1);

                    }

            }

            for(list=0; list<h->list_count; list++){

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

                    unsigned int val;

                    if(IS_DIR(mb_type, i, list)){

                        pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mx, &my);

                        mx += get_se_golomb(&s->gb);

                        my += get_se_golomb(&s->gb);

                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                        val= pack16to32(mx,my);

                    }else

                        val=0;

                    fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 4);

                }

            }

        }else{

            assert(IS_8X16(mb_type));

            for(list=0; list<h->list_count; list++){

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

                        unsigned int val;

                        if(IS_DIR(mb_type, i, list)){ //FIXME optimize

                            val= get_te0_golomb(&s->gb, h->ref_count[list]);

                            if(val >= h->ref_count[list]){

                                av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);

                                return -1;

                            }

                        }else

                            val= LIST_NOT_USED&0xFF;

                        fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 1);

                    }

            }

            for(list=0; list<h->list_count; list++){

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

                    unsigned int val;

                    if(IS_DIR(mb_type, i, list)){

                        pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);

                        mx += get_se_golomb(&s->gb);

                        my += get_se_golomb(&s->gb);

                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                        val= pack16to32(mx,my);

                    }else

                        val=0;

                    fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 4);

                }

            }

        }

    }

    if(IS_INTER(mb_type))

        write_back_motion(h, mb_type);

    if(!IS_INTRA16x16(mb_type)){

        cbp= get_ue_golomb(&s->gb);

        if(cbp > 47){

            av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y);

            return -1;

        }

        if(IS_INTRA4x4(mb_type))

            cbp= golomb_to_intra4x4_cbp[cbp];

        else

            cbp= golomb_to_inter_cbp[cbp];

    }

    h->cbp = cbp;

    if(dct8x8_allowed && (cbp&15) && !IS_INTRA(mb_type)){

        if(get_bits1(&s->gb))

            mb_type |= MB_TYPE_8x8DCT;

    }

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

    if(cbp || IS_INTRA16x16(mb_type)){

        int i8x8, i4x4, chroma_idx;

        int dquant;

        GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr;

        const uint8_t *scan, *scan8x8, *dc_scan;

//        fill_non_zero_count_cache(h);

        if(IS_INTERLACED(mb_type)){

            scan8x8= s->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;

            scan= s->qscale ? h->field_scan : h->field_scan_q0;

            dc_scan= luma_dc_field_scan;

        }else{

            scan8x8= s->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0;

            scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0;

            dc_scan= luma_dc_zigzag_scan;

        }

        dquant= get_se_golomb(&s->gb);

        if( dquant > 25 || dquant < -26 ){

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

            return -1;

        }

        s->qscale += dquant;

        if(((unsigned)s->qscale) > 51){

            if(s->qscale<0) s->qscale+= 52;

            else            s->qscale-= 52;

        }

        h->chroma_qp[0]= get_chroma_qp(h, 0, s->qscale);

        h->chroma_qp[1]= get_chroma_qp(h, 1, s->qscale);

        if(IS_INTRA16x16(mb_type)){

            if( decode_residual(h, h->intra_gb_ptr, h->mb, LUMA_DC_BLOCK_INDEX, dc_scan, h->dequant4_coeff[0][s->qscale], 16) < 0){

                return -1; //FIXME continue if partitioned and other return -1 too

            }

            assert((cbp&15) == 0 || (cbp&15) == 15);

            if(cbp&15){

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

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

                        const int index= i4x4 + 4*i8x8;

                        if( decode_residual(h, h->intra_gb_ptr, h->mb + 16*index, index, scan + 1, h->dequant4_coeff[0][s->qscale], 15) < 0 ){

                            return -1;

                        }

                    }

                }

            }else{

                fill_rectangle(&h->non_zero_count_cache[scan8[0]], 4, 4, 8, 0, 1);

            }

        }else{

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

                if(cbp & (1<<i8x8)){

                    if(IS_8x8DCT(mb_type)){

                        DCTELEM *buf = &h->mb[64*i8x8];

                        uint8_t *nnz;

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

                            if( decode_residual(h, gb, buf, i4x4+4*i8x8, scan8x8+16*i4x4,

                                                h->dequant8_coeff[IS_INTRA( mb_type ) ? 0:1][s->qscale], 16) <0 )

                                return -1;

                        }

                        nnz= &h->non_zero_count_cache[ scan8[4*i8x8] ];

                        nnz[0] += nnz[1] + nnz[8] + nnz[9];

                    }else{

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

                            const int index= i4x4 + 4*i8x8;

                            if( decode_residual(h, gb, h->mb + 16*index, index, scan, h->dequant4_coeff[IS_INTRA( mb_type ) ? 0:3][s->qscale], 16) <0 ){

                                return -1;

                            }

                        }

                    }

                }else{

                    uint8_t * const nnz= &h->non_zero_count_cache[ scan8[4*i8x8] ];

                    nnz[0] = nnz[1] = nnz[8] = nnz[9] = 0;

                }

            }

        }

        if(cbp&0x30){

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

                if( decode_residual(h, gb, h->mb + 256 + 16*4*chroma_idx, CHROMA_DC_BLOCK_INDEX, chroma_dc_scan, NULL, 4) < 0){

                    return -1;

                }

        }

        if(cbp&0x20){

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

                const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]];

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

                    const int index= 16 + 4*chroma_idx + i4x4;

                    if( decode_residual(h, gb, h->mb + 16*index, index, scan + 1, qmul, 15) < 0){

                        return -1;

                    }

                }

            }

        }else{

            uint8_t * const nnz= &h->non_zero_count_cache[0];

            nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] =

            nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0;

        }

    }else{

        uint8_t * const nnz= &h->non_zero_count_cache[0];

        fill_rectangle(&nnz[scan8[0]], 4, 4, 8, 0, 1);

        nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] =

        nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0;

    }

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

    write_back_non_zero_count(h);

    if(MB_MBAFF){

        h->ref_count[0] >>= 1;

        h->ref_count[1] >>= 1;

    }

    return 0;

}


static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t *scan,

                           const int32_t quant_matrices[16][64], int q)

{

    int coef_list[128];

    int mode_list[128];

    int i, t, mask, bits, ccoef, mode, sign;

    int list_start = 64, list_end = 64, list_pos;

    int coef_count = 0;

    int coef_idx[64];

    int quant_idx;

    const int32_t *quant;

    coef_list[list_end] = 4;  mode_list[list_end++] = 0;

    coef_list[list_end] = 24; mode_list[list_end++] = 0;

    coef_list[list_end] = 44; mode_list[list_end++] = 0;

    coef_list[list_end] = 1;  mode_list[list_end++] = 3;

    coef_list[list_end] = 2;  mode_list[list_end++] = 3;

    coef_list[list_end] = 3;  mode_list[list_end++] = 3;

    bits = get_bits(gb, 4) - 1;

    for (mask = 1 << bits; bits >= 0; mask >>= 1, bits--) {

        list_pos = list_start;

        while (list_pos < list_end) {

            if (!(mode_list[list_pos] | coef_list[list_pos]) || !get_bits1(gb)) {

                list_pos++;

                continue;

            }

            ccoef = coef_list[list_pos];

            mode  = mode_list[list_pos];

            switch (mode) {

            case 0:

                coef_list[list_pos] = ccoef + 4;

                mode_list[list_pos] = 1;

            case 2:

                if (mode == 2) {

                    coef_list[list_pos]   = 0;

                    mode_list[list_pos++] = 0;

                }

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

                    if (get_bits1(gb)) {

                        coef_list[--list_start] = ccoef;

                        mode_list[  list_start] = 3;

                    } else {

                        if (!bits) {

                            t = 1 - (get_bits1(gb) << 1);

                        } else {

                            t = get_bits(gb, bits) | mask;

                            sign = -get_bits1(gb);

                            t = (t ^ sign) - sign;

                        }

                        block[scan[ccoef]] = t;

                        coef_idx[coef_count++] = ccoef;

                    }

                }

                break;

            case 1:

                mode_list[list_pos] = 2;

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

                    ccoef += 4;

                    coef_list[list_end]   = ccoef;

                    mode_list[list_end++] = 2;

                }

                break;

            case 3:

                if (!bits) {

                    t = 1 - (get_bits1(gb) << 1);

                } else {

                    t = get_bits(gb, bits) | mask;

                    sign = -get_bits1(gb);

                    t = (t ^ sign) - sign;

                }

                block[scan[ccoef]] = t;

                coef_idx[coef_count++] = ccoef;

                coef_list[list_pos]   = 0;

                mode_list[list_pos++] = 0;

                break;

            }

        }

    }

    if (q == -1) {

        quant_idx = get_bits(gb, 4);

    } else {

        quant_idx = q;

    }

    quant = quant_matrices[quant_idx];

    block[0] = (block[0] * quant[0]) >> 11;

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

        int idx = coef_idx[i];

        block[scan[idx]] = (block[scan[idx]] * quant[idx]) >> 11;

    }

    return 0;

}


static int decode_rle(CamtasiaContext *c)

{

    unsigned char *src = c->decomp_buf;

    unsigned char *output;

    int p1, p2, line=c->height, pos=0, i;

    output = c->pic.data[0] + (c->height - 1) * c->pic.linesize[0];

    while(src < c->decomp_buf + c->decomp_size) {

        p1 = *src++;

        if(p1 == 0) { //Escape code

            p2 = *src++;

            if(p2 == 0) { //End-of-line

                output = c->pic.data[0] + (--line) * c->pic.linesize[0];

                pos = 0;

                continue;

            } else if(p2 == 1) { //End-of-picture

                return 0;

            } else if(p2 == 2) { //Skip

                p1 = *src++;

                p2 = *src++;

                line -= p2;

                pos += p1;

                output = c->pic.data[0] + line * c->pic.linesize[0] + pos * (c->bpp / 8);

                continue;

            }

            // Copy data

            for(i = 0; i < p2 * (c->bpp / 8); i++) {

                *output++ = *src++;

            }

	    // RLE8 copy is actually padded - and runs are not!

	    if(c->bpp == 8 && (p2 & 1)) {

		src++;

	    }

            pos += p2;

        } else { //Run of pixels

            int pix[3]; //original pixel

            switch(c->bpp){

            case  8: pix[0] = *src++;

                     break;

            case 16: pix[0] = *src++;

                     pix[1] = *src++;

                     break;

            case 24: pix[0] = *src++;

                     pix[1] = *src++;

                     pix[2] = *src++;

                     break;

            }

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

                switch(c->bpp){

                case  8: *output++ = pix[0];

                         break;

                case 16: *output++ = pix[0];

                         *output++ = pix[1];

                         break;

                case 24: *output++ = pix[0];

                         *output++ = pix[1];

                         *output++ = pix[2];

                         break;

                }

            }

            pos += p1;

        }

    }

    av_log(c->avctx, AV_LOG_ERROR, "Camtasia warning: no End-of-picture code\n");

    return 1;

}