static CharDriverState *qemu_chr_open_pp_fd(int fd,

                                            ChardevCommon *backend,

                                            Error **errp)

{

    CharDriverState *chr;

    ParallelCharDriver *drv;

    if (ioctl(fd, PPCLAIM) < 0) {

        error_setg_errno(errp, errno, "not a parallel port");

        close(fd);

        return NULL;

    }

    drv = g_new0(ParallelCharDriver, 1);

    drv->fd = fd;

    drv->mode = IEEE1284_MODE_COMPAT;

    chr = qemu_chr_alloc(backend, errp);

    if (!chr) {

        return NULL;

    }

    chr->chr_write = null_chr_write;

    chr->chr_ioctl = pp_ioctl;

    chr->chr_close = pp_close;

    chr->opaque = drv;

    return chr;

}


static void pprint_data(V9fsPDU *pdu, int rx, size_t *offsetp, const char *name)

{

    struct iovec *sg = get_sg(pdu, rx);

    size_t offset = *offsetp;

    unsigned int count;

    int32_t size;

    int total, i, j;

    ssize_t len;

    if (rx) {

        count = pdu->elem.in_num;

    } else

        count = pdu->elem.out_num;

    }


static void put_audio_specific_config(AVCodecContext *avctx)

{

    PutBitContext pb;

    AACEncContext *s = avctx->priv_data;

    init_put_bits(&pb, avctx->extradata, avctx->extradata_size*8);

    put_bits(&pb, 5, 2); //object type - AAC-LC

    put_bits(&pb, 4, s->samplerate_index); //sample rate index

    put_bits(&pb, 4, s->channels);

    //GASpecificConfig

    put_bits(&pb, 1, 0); //frame length - 1024 samples

    put_bits(&pb, 1, 0); //does not depend on core coder

    put_bits(&pb, 1, 0); //is not extension

    //Explicitly Mark SBR absent

    put_bits(&pb, 11, 0x2b7); //sync extension

    put_bits(&pb, 5,  AOT_SBR);

    put_bits(&pb, 1,  0);

    flush_put_bits(&pb);

}


static void error_setv(Error **errp, ErrorClass err_class,

                       const char *fmt, va_list ap)

{

    Error *err;

    int saved_errno = errno;

    if (errp == NULL) {

        return;

    }

    assert(*errp == NULL);

    err = g_malloc0(sizeof(*err));

    err->msg = g_strdup_vprintf(fmt, ap);

    err->err_class = err_class;

    if (errp == &error_abort) {

        error_report_err(err);

        abort();

    }

    *errp = err;

    errno = saved_errno;

}


static QObject *qdict_get_obj(const QDict *qdict, const char *key, QType type)

{

    QObject *obj;

    obj = qdict_get(qdict, key);

    assert(obj != NULL);

    assert(qobject_type(obj) == type);

    return obj;

}


static av_cold int libschroedinger_encode_init(AVCodecContext *avctx)

{

    SchroEncoderParams *p_schro_params = avctx->priv_data;

    SchroVideoFormatEnum preset;

    /* Initialize the libraries that libschroedinger depends on. */

    schro_init();

    /* Create an encoder object. */

    p_schro_params->encoder = schro_encoder_new();

    if (!p_schro_params->encoder) {

        av_log(avctx, AV_LOG_ERROR,

               "Unrecoverable Error: schro_encoder_new failed. ");

        return -1;

    }

    /* Initialize the format. */

    preset = ff_get_schro_video_format_preset(avctx);

    p_schro_params->format =

                    schro_encoder_get_video_format(p_schro_params->encoder);

    schro_video_format_set_std_video_format(p_schro_params->format, preset);

    p_schro_params->format->width  = avctx->width;

    p_schro_params->format->height = avctx->height;

    if (set_chroma_format(avctx) == -1)

        return -1;

    if (avctx->color_primaries == AVCOL_PRI_BT709) {

        p_schro_params->format->colour_primaries = SCHRO_COLOUR_PRIMARY_HDTV;

    } else if (avctx->color_primaries == AVCOL_PRI_BT470BG) {

        p_schro_params->format->colour_primaries = SCHRO_COLOUR_PRIMARY_SDTV_625;

    } else if (avctx->color_primaries == AVCOL_PRI_SMPTE170M) {

        p_schro_params->format->colour_primaries = SCHRO_COLOUR_PRIMARY_SDTV_525;

    }

    if (avctx->colorspace == AVCOL_SPC_BT709) {

        p_schro_params->format->colour_matrix = SCHRO_COLOUR_MATRIX_HDTV;

    } else if (avctx->colorspace == AVCOL_SPC_BT470BG) {

        p_schro_params->format->colour_matrix = SCHRO_COLOUR_MATRIX_SDTV;

    }

    if (avctx->color_trc == AVCOL_TRC_BT709) {

        p_schro_params->format->transfer_function = SCHRO_TRANSFER_CHAR_TV_GAMMA;

    }

    if (ff_get_schro_frame_format(p_schro_params->format->chroma_format,

                                  &p_schro_params->frame_format) == -1) {

        av_log(avctx, AV_LOG_ERROR,

               "This codec currently supports only planar YUV 4:2:0, 4:2:2"

               " and 4:4:4 formats.\n");

        return -1;

    }

    p_schro_params->format->frame_rate_numerator   = avctx->time_base.den;

    p_schro_params->format->frame_rate_denominator = avctx->time_base.num;

    p_schro_params->frame_size = av_image_get_buffer_size(avctx->pix_fmt,

                                                          avctx->width,

                                                          avctx->height, 1);

    if (!avctx->gop_size) {

        schro_encoder_setting_set_double(p_schro_params->encoder,

                                         "gop_structure",

                                         SCHRO_ENCODER_GOP_INTRA_ONLY);

#if FF_API_CODER_TYPE

FF_DISABLE_DEPRECATION_WARNINGS

        if (avctx->coder_type != FF_CODER_TYPE_VLC)

            p_schro_params->noarith = 0;

FF_ENABLE_DEPRECATION_WARNINGS

#endif

        schro_encoder_setting_set_double(p_schro_params->encoder,

                                         "enable_noarith",

                                         p_schro_params->noarith);

    } else {

        schro_encoder_setting_set_double(p_schro_params->encoder,

                                         "au_distance", avctx->gop_size);

        avctx->has_b_frames = 1;

        p_schro_params->dts = -1;

    }

    /* FIXME - Need to handle SCHRO_ENCODER_RATE_CONTROL_LOW_DELAY. */

    if (avctx->flags & AV_CODEC_FLAG_QSCALE) {

        if (!avctx->global_quality) {

            /* lossless coding */

            schro_encoder_setting_set_double(p_schro_params->encoder,

                                             "rate_control",

                                             SCHRO_ENCODER_RATE_CONTROL_LOSSLESS);

        } else {

            int quality;

            schro_encoder_setting_set_double(p_schro_params->encoder,

                                             "rate_control",

                                             SCHRO_ENCODER_RATE_CONTROL_CONSTANT_QUALITY);

            quality = avctx->global_quality / FF_QP2LAMBDA;

            if (quality > 10)

                quality = 10;

            schro_encoder_setting_set_double(p_schro_params->encoder,

                                             "quality", quality);

        }

    } else {

        schro_encoder_setting_set_double(p_schro_params->encoder,

                                         "rate_control",

                                         SCHRO_ENCODER_RATE_CONTROL_CONSTANT_BITRATE);

        schro_encoder_setting_set_double(p_schro_params->encoder,

                                         "bitrate", avctx->bit_rate);

    }

    if (avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)

        /* All material can be coded as interlaced or progressive

           irrespective of the type of source material. */

        schro_encoder_setting_set_double(p_schro_params->encoder,

                                         "interlaced_coding", 1);

    schro_encoder_setting_set_double(p_schro_params->encoder, "open_gop",

                                     !(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP));

    /* FIXME: Signal range hardcoded to 8-bit data until both libschroedinger

     * and libdirac support other bit-depth data. */

    schro_video_format_set_std_signal_range(p_schro_params->format,

                                            SCHRO_SIGNAL_RANGE_8BIT_VIDEO);

    /* Set the encoder format. */

    schro_encoder_set_video_format(p_schro_params->encoder,

                                   p_schro_params->format);

    /* Set the debug level. */

    schro_debug_set_level(avctx->debug);

    schro_encoder_start(p_schro_params->encoder);

    /* Initialize the encoded frame queue. */

    ff_schro_queue_init(&p_schro_params->enc_frame_queue);

    return 0;

}


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

                            int *got_frame_ptr, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    int channel_mask;

    int channel_layout;

    int lfe_samples;

    int num_core_channels = 0;

    int i, ret;

    float **samples_flt;

    float *src_chan;

    float *dst_chan;

    DCAContext *s = avctx->priv_data;

    int core_ss_end;

    int channels, full_channels;

    float scale;

    int achan;

    int chset;

    int mask;

    int lavc;

    int posn;

    int j, k;

    int endch;

    s->xch_present = 0;

    s->dca_buffer_size = ff_dca_convert_bitstream(buf, buf_size, s->dca_buffer,

                                                  DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE);

    if (s->dca_buffer_size == AVERROR_INVALIDDATA) {

        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 ((ret = dca_parse_frame_header(s)) < 0) {

        //seems like the frame is corrupt, try with the next one

        return ret;

    }

    //set AVCodec values with parsed data

    avctx->sample_rate = s->sample_rate;

    avctx->bit_rate    = s->bit_rate;

    s->profile = FF_PROFILE_DTS;

    for (i = 0; i < (s->sample_blocks / 8); i++) {

        if ((ret = dca_decode_block(s, 0, i))) {

            av_log(avctx, AV_LOG_ERROR, "error decoding block\n");

            return ret;

        }

    }

    /* record number of core channels incase less than max channels are requested */

    num_core_channels = s->prim_channels;

    if (s->ext_coding)

        s->core_ext_mask = dca_ext_audio_descr_mask[s->ext_descr];

    else

        s->core_ext_mask = 0;

    core_ss_end = FFMIN(s->frame_size, s->dca_buffer_size) * 8;

    /* only scan for extensions if ext_descr was unknown or indicated a

     * supported XCh extension */

    if (s->core_ext_mask < 0 || s->core_ext_mask & (DCA_EXT_XCH | DCA_EXT_XXCH)) {

        /* if ext_descr was unknown, clear s->core_ext_mask so that the

         * extensions scan can fill it up */

        s->core_ext_mask = FFMAX(s->core_ext_mask, 0);

        /* extensions start at 32-bit boundaries into bitstream */

        skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);

        while (core_ss_end - get_bits_count(&s->gb) >= 32) {

            uint32_t bits = get_bits_long(&s->gb, 32);

            switch (bits) {

            case 0x5a5a5a5a: {

                int ext_amode, xch_fsize;

                s->xch_base_channel = s->prim_channels;

                /* validate sync word using XCHFSIZE field */

                xch_fsize = show_bits(&s->gb, 10);

                if ((s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + xch_fsize) &&

                    (s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + xch_fsize + 1))

                    continue;

                /* skip length-to-end-of-frame field for the moment */

                skip_bits(&s->gb, 10);

                s->core_ext_mask |= DCA_EXT_XCH;

                /* extension amode(number of channels in extension) should be 1 */

                /* AFAIK XCh is not used for more channels */

                if ((ext_amode = get_bits(&s->gb, 4)) != 1) {

                    av_log(avctx, AV_LOG_ERROR, "XCh extension amode %d not"

                           " supported!\n", ext_amode);

                    continue;

                }

                if (s->xch_base_channel < 2) {

                    av_log_ask_for_sample(avctx, "XCh with fewer than 2 base channels is not supported\n");

                    continue;

                }

                /* much like core primary audio coding header */

                dca_parse_audio_coding_header(s, s->xch_base_channel, 0);

                for (i = 0; i < (s->sample_blocks / 8); i++)

                    if ((ret = dca_decode_block(s, s->xch_base_channel, i))) {

                        av_log(avctx, AV_LOG_ERROR, "error decoding XCh extension\n");

                        continue;

                    }

                s->xch_present = 1;

                break;

            }

            case 0x47004a03:

                /* XXCh: extended channels */

                /* usually found either in core or HD part in DTS-HD HRA streams,

                 * but not in DTS-ES which contains XCh extensions instead */

                s->core_ext_mask |= DCA_EXT_XXCH;

                dca_xxch_decode_frame(s);

                break;

            case 0x1d95f262: {

                int fsize96 = show_bits(&s->gb, 12) + 1;

                if (s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + fsize96)

                    continue;

                av_log(avctx, AV_LOG_DEBUG, "X96 extension found at %d bits\n",

                       get_bits_count(&s->gb));

                skip_bits(&s->gb, 12);

                av_log(avctx, AV_LOG_DEBUG, "FSIZE96 = %d bytes\n", fsize96);

                av_log(avctx, AV_LOG_DEBUG, "REVNO = %d\n", get_bits(&s->gb, 4));

                s->core_ext_mask |= DCA_EXT_X96;

                break;

            }

            }

            skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);

        }

    } else {

        /* no supported extensions, skip the rest of the core substream */

        skip_bits_long(&s->gb, core_ss_end - get_bits_count(&s->gb));

    }

    if (s->core_ext_mask & DCA_EXT_X96)

        s->profile = FF_PROFILE_DTS_96_24;

    else if (s->core_ext_mask & (DCA_EXT_XCH | DCA_EXT_XXCH))

        s->profile = FF_PROFILE_DTS_ES;

    /* check for ExSS (HD part) */

    if (s->dca_buffer_size - s->frame_size > 32 &&

        get_bits_long(&s->gb, 32) == DCA_HD_MARKER)

        dca_exss_parse_header(s);

    avctx->profile = s->profile;

    full_channels = channels = s->prim_channels + !!s->lfe;

    /* If we have XXCH then the channel layout is managed differently */

    /* note that XLL will also have another way to do things */

    if (!(s->core_ext_mask & DCA_EXT_XXCH)

        || (s->core_ext_mask & DCA_EXT_XXCH && avctx->request_channels > 0

            && avctx->request_channels

            < num_core_channels + !!s->lfe + s->xxch_chset_nch[0]))

    { /* xxx should also do MA extensions */

        if (s->amode < 16) {

            avctx->channel_layout = dca_core_channel_layout[s->amode];

            if (s->xch_present && (!avctx->request_channels ||

                                   avctx->request_channels

                                   > num_core_channels + !!s->lfe)) {

                avctx->channel_layout |= AV_CH_BACK_CENTER;

                if (s->lfe) {

                    avctx->channel_layout |= AV_CH_LOW_FREQUENCY;

                    s->channel_order_tab = dca_channel_reorder_lfe_xch[s->amode];

                } else {

                    s->channel_order_tab = dca_channel_reorder_nolfe_xch[s->amode];

                }

            } else {

                channels = num_core_channels + !!s->lfe;

                s->xch_present = 0; /* disable further xch processing */

                if (s->lfe) {

                    avctx->channel_layout |= AV_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 (channels > !!s->lfe &&

                s->channel_order_tab[channels - 1 - !!s->lfe] < 0)

            if (av_get_channel_layout_nb_channels(avctx->channel_layout) != channels) {

                av_log(avctx, AV_LOG_ERROR, "Number of channels %d mismatches layout %d\n", channels, av_get_channel_layout_nb_channels(avctx->channel_layout));

            }

            if (avctx->request_channels == 2 && s->prim_channels > 2) {

                channels = 2;

                s->output = DCA_STEREO;

                avctx->channel_layout = AV_CH_LAYOUT_STEREO;

            }

            else if (avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE) {

                static const int8_t dca_channel_order_native[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };

                s->channel_order_tab = dca_channel_order_native;

            }

            s->lfe_index = dca_lfe_index[s->amode];

        } else {

            av_log(avctx, AV_LOG_ERROR,

                   "Non standard configuration %d !\n", s->amode);

        }

        s->xxch_dmix_embedded = 0;

    } else {

        /* we only get here if an XXCH channel set can be added to the mix */

        channel_mask = s->xxch_core_spkmask;

        if (avctx->request_channels > 0

            && avctx->request_channels < s->prim_channels) {

            channels = num_core_channels + !!s->lfe;

            for (i = 0; i < s->xxch_chset && channels + s->xxch_chset_nch[i]

                                              <= avctx->request_channels; i++) {

                channels += s->xxch_chset_nch[i];

                channel_mask |= s->xxch_spk_masks[i];

            }

        } else {

            channels = s->prim_channels + !!s->lfe;

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

                channel_mask |= s->xxch_spk_masks[i];

            }

        }

        /* Given the DTS spec'ed channel mask, generate an avcodec version */

        channel_layout = 0;

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

            if (channel_mask & (1 << i)) {

                channel_layout |= map_xxch_to_native[i];

            }

        }

        /* make sure that we have managed to get equivelant dts/avcodec channel

         * masks in some sense -- unfortunately some channels could overlap */

        if (av_popcount(channel_mask) != av_popcount(channel_layout)) {

            av_log(avctx, AV_LOG_DEBUG,

                   "DTS-XXCH: Inconsistant avcodec/dts channel layouts\n");

        }

        avctx->channel_layout = channel_layout;

        if (!(avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE)) {

            /* Estimate DTS --> avcodec ordering table */

            for (chset = -1, j = 0; chset < s->xxch_chset; ++chset) {

                mask = chset >= 0 ? s->xxch_spk_masks[chset]

                                  : s->xxch_core_spkmask;

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

                    if (mask & ~(DCA_XXCH_LFE1 | DCA_XXCH_LFE2) & (1 << i)) {

                        lavc = map_xxch_to_native[i];

                        posn = av_popcount(channel_layout & (lavc - 1));

                        s->xxch_order_tab[j++] = posn;

                    }

                }

            }

            s->lfe_index = av_popcount(channel_layout & (AV_CH_LOW_FREQUENCY-1));

        } else { /* native ordering */

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

                s->xxch_order_tab[i] = i;

            s->lfe_index = channels - 1;

        }

        s->channel_order_tab = s->xxch_order_tab;

    }

    if (avctx->channels != channels) {

        if (avctx->channels)

            av_log(avctx, AV_LOG_INFO, "Number of channels changed in DCA decoder (%d -> %d)\n", avctx->channels, channels);

        avctx->channels = channels;

    }

    /* get output buffer */

    s->frame.nb_samples = 256 * (s->sample_blocks / 8);

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

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

        return ret;

    }

    samples_flt = (float  **) s->frame.extended_data;

    /* allocate buffer for extra channels if downmixing */

    if (avctx->channels < full_channels) {

        ret = av_samples_get_buffer_size(NULL, full_channels - channels,

                                         s->frame.nb_samples,

                                         avctx->sample_fmt, 0);

        if (ret < 0)

            return ret;

        av_fast_malloc(&s->extra_channels_buffer,

                       &s->extra_channels_buffer_size, ret);

        if (!s->extra_channels_buffer)

            return AVERROR(ENOMEM);

        ret = av_samples_fill_arrays((uint8_t **)s->extra_channels, NULL,

                                     s->extra_channels_buffer,

                                     full_channels - channels,

                                     s->frame.nb_samples, avctx->sample_fmt, 0);

        if (ret < 0)

            return ret;

    }

    /* filter to get final output */

    for (i = 0; i < (s->sample_blocks / 8); i++) {

        int ch;

        for (ch = 0; ch < channels; ch++)

            s->samples_chanptr[ch] = samples_flt[ch] + i * 256;

        for (; ch < full_channels; ch++)

            s->samples_chanptr[ch] = s->extra_channels[ch - channels] + i * 256;

        dca_filter_channels(s, i);

        /* If this was marked as a DTS-ES stream we need to subtract back- */

        /* channel from SL & SR to remove matrixed back-channel signal */

        if ((s->source_pcm_res & 1) && s->xch_present) {

            float *back_chan = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel]];

            float *lt_chan   = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel - 2]];

            float *rt_chan   = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel - 1]];

            s->fdsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);

            s->fdsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256);

        }

        /* If stream contains XXCH, we might need to undo an embedded downmix */

        if (s->xxch_dmix_embedded) {

            /* Loop over channel sets in turn */

            ch = num_core_channels;

            for (chset = 0; chset < s->xxch_chset; chset++) {

                endch = ch + s->xxch_chset_nch[chset];

                mask = s->xxch_dmix_embedded;

                /* undo downmix */

                for (j = ch; j < endch; j++) {

                    if (mask & (1 << j)) { /* this channel has been mixed-out */

                        src_chan = s->samples_chanptr[s->channel_order_tab[j]];

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

                            achan = s->channel_order_tab[k];

                            scale = s->xxch_dmix_coeff[j][k];

                            if (scale != 0.0) {

                                dst_chan = s->samples_chanptr[achan];

                                s->fdsp.vector_fmac_scalar(dst_chan, src_chan,

                                                           -scale, 256);

                            }

                        }

                    }

                }

                /* if a downmix has been embedded then undo the pre-scaling */

                if ((mask & (1 << ch)) && s->xxch_dmix_sf[chset] != 1.0f) {

                    scale = s->xxch_dmix_sf[chset];

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

                        src_chan = s->samples_chanptr[s->channel_order_tab[j]];

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

                            src_chan[k] *= scale;

                    }

                    /* LFE channel is always part of core, scale if it exists */

                    if (s->lfe) {

                        src_chan = s->samples_chanptr[s->lfe_index];

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

                            src_chan[k] *= scale;

                    }

                }

                ch = endch;

            }

        }

    }

    /* update lfe history */

    lfe_samples = 2 * s->lfe * (s->sample_blocks / 8);

    for (i = 0; i < 2 * s->lfe * 4; i++)

        s->lfe_data[i] = s->lfe_data[i + lfe_samples];

    *got_frame_ptr    = 1;

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

    return buf_size;

}


static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride,

                             const uint8_t *src, int size, int lines)

{

    int c, line, pixels, code, ret;

    const uint8_t *ssrc = src;

    int width           = ((s->width * s->bpp) + 7) >> 3;

    if (size <= 0)

        return AVERROR_INVALIDDATA;

    if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) {

#if CONFIG_ZLIB

        return tiff_unpack_zlib(s, dst, stride, src, size, width, lines);

#else

        av_log(s->avctx, AV_LOG_ERROR,

               "zlib support not enabled, "

               "deflate compression not supported\n");

        return AVERROR(ENOSYS);

#endif

    }

    if (s->compr == TIFF_LZW) {

        if ((ret = ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF)) < 0) {

            av_log(s->avctx, AV_LOG_ERROR, "Error initializing LZW decoder\n");

            return ret;

        }

    }

    if (s->compr == TIFF_CCITT_RLE ||

        s->compr == TIFF_G3        ||

        s->compr == TIFF_G4) {

        return tiff_unpack_fax(s, dst, stride, src, size, lines);

    }

    for (line = 0; line < lines; line++) {

        if (src - ssrc > size) {

            av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");

            return AVERROR_INVALIDDATA;

        }

        switch (s->compr) {

        case TIFF_RAW:

            if (ssrc + size - src < width)

                return AVERROR_INVALIDDATA;

            if (!s->fill_order) {

                memcpy(dst, src, width);

            } else {

                int i;

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

                    dst[i] = ff_reverse[src[i]];

            }

            src += width;

            break;

        case TIFF_PACKBITS:

            for (pixels = 0; pixels < width;) {

                code = (int8_t) *src++;

                if (code >= 0) {

                    code++;

                    if (pixels + code > width) {

                        av_log(s->avctx, AV_LOG_ERROR,

                               "Copy went out of bounds\n");

                        return AVERROR_INVALIDDATA;

                    }

                    memcpy(dst + pixels, src, code);

                    src    += code;

                    pixels += code;

                } else if (code != -128) { // -127..-1

                    code = (-code) + 1;

                    if (pixels + code > width) {

                        av_log(s->avctx, AV_LOG_ERROR,

                               "Run went out of bounds\n");

                        return AVERROR_INVALIDDATA;

                    }

                    c = *src++;

                    memset(dst + pixels, c, code);

                    pixels += code;

                }

            }

            break;

        case TIFF_LZW:

            pixels = ff_lzw_decode(s->lzw, dst, width);

            if (pixels < width) {

                av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n",

                       pixels, width);

                return AVERROR_INVALIDDATA;

            }

            break;

        }

        dst += stride;

    }

    return 0;

}


AVBitStreamFilterContext *av_bitstream_filter_init(const char *name){

    AVBitStreamFilter *bsf= first_bitstream_filter;

    while(bsf){

        if(!strcmp(name, bsf->name)){

            AVBitStreamFilterContext *bsfc= av_mallocz(sizeof(AVBitStreamFilterContext));

            bsfc->filter= bsf;

            bsfc->priv_data= av_mallocz(bsf->priv_data_size);

            return bsfc;

        }

        bsf= bsf->next;

    }

    return NULL;

}


void ff_avg_h264_qpel8_mc22_msa(uint8_t *dst, const uint8_t *src,

                                ptrdiff_t stride)

{

    avc_luma_mid_and_aver_dst_8w_msa(src - (2 * stride) - 2,

                                     stride, dst, stride, 8);

}


static int ac3_decode_init(AVCodecContext *avctx)

{

    AC3DecodeContext *ctx = avctx->priv_data;

    ac3_common_init();

    ff_mdct_init(&ctx->imdct_ctx_256, 8, 1);

    ff_mdct_init(&ctx->imdct_ctx_512, 9, 1);

    ctx->samples = av_mallocz(6 * 256 * sizeof (float));

    if (!ctx->samples) {

        av_log(avctx, AV_LOG_ERROR, "Cannot allocate memory for samples\n");

        return -1;

    }

    dither_seed(&ctx->state, 0);

    return 0;

}


static av_cold int flashsv_encode_init(AVCodecContext *avctx)

{

    FlashSVContext *s = avctx->priv_data;

    s->avctx = avctx;

    if (avctx->width > 4095 || avctx->height > 4095) {

        av_log(avctx, AV_LOG_ERROR,

               "Input dimensions too large, input must be max 4096x4096 !\n");

        return AVERROR_INVALIDDATA;

    }

    // Needed if zlib unused or init aborted before deflateInit

    memset(&s->zstream, 0, sizeof(z_stream));

    s->last_key_frame = 0;

    s->image_width  = avctx->width;

    s->image_height = avctx->height;

    s->tmpblock  = av_mallocz(3 * 256 * 256);

    s->encbuffer = av_mallocz(s->image_width * s->image_height * 3);

    if (!s->tmpblock || !s->encbuffer) {

        av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n");

        return AVERROR(ENOMEM);

    }

    avctx->coded_frame = av_frame_alloc();

    if (!avctx->coded_frame) {

        flashsv_encode_end(avctx);

        return AVERROR(ENOMEM);

    }

    return 0;

}


static int subtitle_thread(void *arg)

{

    VideoState *is = arg;

    Frame *sp;

    int got_subtitle;

    double pts;

    int i;

    for (;;) {

        if (!(sp = frame_queue_peek_writable(&is->subpq)))

            return 0;

        if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)

            break;

        pts = 0;

        if (got_subtitle && sp->sub.format == 0) {

            if (sp->sub.pts != AV_NOPTS_VALUE)

                pts = sp->sub.pts / (double)AV_TIME_BASE;

            sp->pts = pts;

            sp->serial = is->subdec.pkt_serial;

            for (i = 0; i < sp->sub.num_rects; i++)

            {

                int in_w = sp->sub.rects[i]->w;

                int in_h = sp->sub.rects[i]->h;

                int subw = is->subdec.avctx->width  ? is->subdec.avctx->width  : is->viddec_width;

                int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;

                int out_w = is->viddec_width  ? in_w * is->viddec_width  / subw : in_w;

                int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;

                AVPicture newpic;

                //can not use avpicture_alloc as it is not compatible with avsubtitle_free()

                av_image_fill_linesizes(newpic.linesize, AV_PIX_FMT_YUVA420P, out_w);

                newpic.data[0] = av_malloc(newpic.linesize[0] * out_h);

                newpic.data[3] = av_malloc(newpic.linesize[3] * out_h);

                newpic.data[1] = av_malloc(newpic.linesize[1] * ((out_h+1)/2));

                newpic.data[2] = av_malloc(newpic.linesize[2] * ((out_h+1)/2));

                is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,

                    in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,

                    AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);

                if (!is->sub_convert_ctx || !newpic.data[0] || !newpic.data[3] ||

                    !newpic.data[1] || !newpic.data[2]

                ) {

                    av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");

                    exit(1);

                }

                sws_scale(is->sub_convert_ctx,

                          (void*)sp->sub.rects[i]->pict.data, sp->sub.rects[i]->pict.linesize,

                          0, in_h, newpic.data, newpic.linesize);

                av_free(sp->sub.rects[i]->pict.data[0]);

                av_free(sp->sub.rects[i]->pict.data[1]);

                sp->sub.rects[i]->pict = newpic;

                sp->sub.rects[i]->w = out_w;

                sp->sub.rects[i]->h = out_h;

                sp->sub.rects[i]->x = sp->sub.rects[i]->x * out_w / in_w;

                sp->sub.rects[i]->y = sp->sub.rects[i]->y * out_h / in_h;

            }

            /* now we can update the picture count */

            frame_queue_push(&is->subpq);

        } else if (got_subtitle) {

            avsubtitle_free(&sp->sub);

        }

    }

    return 0;

}


static int vb_decode_framedata(VBDecContext *c, const uint8_t *buf, int offset)

{

    uint8_t *prev, *cur;

    int blk, blocks, t, blk2;

    int blocktypes = 0;

    int x, y, a, b;

    int pattype, pattern;

    const int width = c->avctx->width;

    uint8_t *pstart = c->prev_frame;

    uint8_t *pend = c->prev_frame + width*c->avctx->height;

    prev = c->prev_frame + offset;

    cur = c->frame;

    blocks = (c->avctx->width >> 2) * (c->avctx->height >> 2);

    blk2 = 0;

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

        if(!(blk & 3))

            blocktypes = bytestream_get_byte(&buf);

        switch(blocktypes & 0xC0){

        case 0x00: //skip

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

                if(check_line(prev + y*width, pstart, pend))

                    memcpy(cur + y*width, prev + y*width, 4);

                else

                    memset(cur + y*width, 0, 4);

            break;

        case 0x40:

            t = bytestream_get_byte(&buf);

            if(!t){ //raw block

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

                    memcpy(cur + y*width, buf + y*4, 4);

                buf += 16;

            }else{ // motion compensation

                x = ((t & 0xF)^8) - 8;

                y = ((t >> 4) ^8) - 8;

                t = x + y*width;

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

                    if(check_line(prev + t + y*width, pstart, pend))

                        memcpy(cur + y*width, prev + t + y*width, 4);

                    else

                        memset(cur + y*width, 0, 4);

            }

            break;

        case 0x80: // fill

            t = bytestream_get_byte(&buf);

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

                memset(cur + y*width, t, 4);

            break;

        case 0xC0: // pattern fill

            t = bytestream_get_byte(&buf);

            pattype = t >> 6;

            pattern = vb_patterns[t & 0x3F];

            switch(pattype){

            case 0:

                a = bytestream_get_byte(&buf);

                b = bytestream_get_byte(&buf);

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

                    for(x = 0; x < 4; x++, pattern >>= 1)

                        cur[x + y*width] = (pattern & 1) ? b : a;

                break;

            case 1:

                pattern = ~pattern;

            case 2:

                a = bytestream_get_byte(&buf);

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

                    for(x = 0; x < 4; x++, pattern >>= 1)

                        if(pattern & 1 && check_pixel(prev + x + y*width, pstart, pend))

                            cur[x + y*width] = prev[x + y*width];

                        else

                            cur[x + y*width] = a;

                break;

            case 3:

                av_log(c->avctx, AV_LOG_ERROR, "Invalid opcode seen @%d\n",blk);

                return -1;

            }

            break;

        }

        blocktypes <<= 2;

        cur  += 4;

        prev += 4;

        blk2++;

        if(blk2 == (width >> 2)){

            blk2 = 0;

            cur  += width * 3;

            prev += width * 3;

        }

    }

    return 0;

}


static int RENAME(dct_quantize)(MpegEncContext *s,

                            DCTELEM *block, int n,

                            int qscale, int *overflow)

{

    int level=0, last_non_zero_p1, q; //=0 is cuz gcc says uninitalized ...

    const uint16_t *qmat, *bias;

    static __align8 int16_t temp_block[64];

    //s->fdct (block);

    ff_fdct_mmx (block); //cant be anything else ...

    if (s->mb_intra) {

        int dummy;

        if (n < 4)

            q = s->y_dc_scale;

        else

            q = s->c_dc_scale;

        /* note: block[0] is assumed to be positive */

        if (!s->h263_aic) {

#if 1

        asm volatile (

        	"imul %%ecx		\n\t"

        	: "=d" (level), "=a"(dummy)

        	: "a" ((block[0]>>2) + q), "c" (inverse[q<<1])

        );

#else

        asm volatile (

        	"xorl %%edx, %%edx	\n\t"

        	"divw %%cx		\n\t"

        	"movzwl %%ax, %%eax	\n\t"

        	: "=a" (level)

        	: "a" ((block[0]>>2) + q), "c" (q<<1)

        	: "%edx"

        );

#endif

        } else

            /* For AIC we skip quant/dequant of INTRADC */

            level = (block[0] + 4)>>3;

        block[0]=0; //avoid fake overflow

//        temp_block[0] = (block[0] + (q >> 1)) / q;

        last_non_zero_p1 = 1;

        bias = s->q_intra_matrix16_bias[qscale];

        qmat = s->q_intra_matrix16[qscale];

    } else {

        last_non_zero_p1 = 0;

        bias = s->q_inter_matrix16_bias[qscale];

        qmat = s->q_inter_matrix16[qscale];

    }

    if(s->out_format == FMT_H263 && s->mpeg_quant==0){

	  /* PROLOGUE */

        asm volatile(

            "movd %%eax, %%mm3			\n\t" // last_non_zero_p1

            SPREADW(%%mm3)

            "pxor %%mm7, %%mm7			\n\t" // 0

            "pxor %%mm4, %%mm4			\n\t" // 0

            "movq (%1), %%mm5			\n\t" // qmat[0]

            "pxor %%mm6, %%mm6			\n\t"

            "psubw (%2), %%mm6			\n\t" // -bias[0]

            "movl $-128, %%eax			\n\t"

            : "+a" (last_non_zero_p1)

            : "r" (qmat), "r" (bias)

            );

	  /* CORE */

	  asm volatile(

            ".balign 16				\n\t"

            "1:					\n\t"

            "pxor %%mm1, %%mm1			\n\t" // 0

            "movq (%1, %%eax), %%mm0		\n\t" // block[i]

            "pcmpgtw %%mm0, %%mm1		\n\t" // block[i] <= 0 ? 0xFF : 0x00

            "pxor %%mm1, %%mm0			\n\t"

            "psubw %%mm1, %%mm0			\n\t" // ABS(block[i])

            "psubusw %%mm6, %%mm0		\n\t" // ABS(block[i]) + bias[0]

            "pmulhw %%mm5, %%mm0		\n\t" // (ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16

            "por %%mm0, %%mm4			\n\t"

            "pxor %%mm1, %%mm0			\n\t"

            "psubw %%mm1, %%mm0			\n\t" // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i])

            "movq %%mm0, (%3, %%eax)		\n\t"

            "pcmpeqw %%mm7, %%mm0		\n\t" // out==0 ? 0xFF : 0x00

            "movq (%2, %%eax), %%mm1		\n\t"

            "movq %%mm7, (%1, %%eax)		\n\t" // 0

            "pandn %%mm1, %%mm0			\n\t"

	    PMAXW(%%mm0, %%mm3)

            "addl $8, %%eax			\n\t"

            " js 1b				\n\t"

            : "+a" (last_non_zero_p1)

            : "r" (block+64), "r" (inv_zigzag_direct16+64), "r" (temp_block+64)

            );

	  /* EPILOGUE */

	  asm volatile(

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

            "psrlq $32, %%mm3			\n\t"

	    PMAXW(%%mm0, %%mm3)

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

            "psrlq $16, %%mm3			\n\t"

	    PMAXW(%%mm0, %%mm3)

            "movd %%mm3, %%eax			\n\t"

            "movzbl %%al, %%eax			\n\t" // last_non_zero_p1

            "movd %2, %%mm1			\n\t" // max_qcoeff

	    SPREADW(%%mm1)

            "psubusw %%mm1, %%mm4		\n\t"

            "packuswb %%mm4, %%mm4		\n\t"

            "movd %%mm4, %1			\n\t" // *overflow

            : "+a" (last_non_zero_p1), "=r" (*overflow)

            : "r" (s->max_qcoeff)

            );

    }else{ // FMT_H263

        asm volatile(

            "pushl %%ebp				\n\t"

            "pushl %%ebx				\n\t"

            "movl %0, %%ebp				\n\t"

            "movl (%%ebp), %%ebx		\n\t"

            "movd %%ebx, %%mm3			\n\t" // last_non_zero_p1

            SPREADW(%%mm3)

            "pxor %%mm7, %%mm7			\n\t" // 0

            "pxor %%mm4, %%mm4			\n\t" // 0

            "movl $-128, %%ebx			\n\t"

            ".balign 16				\n\t"

            "1:					\n\t"

            "pxor %%mm1, %%mm1			\n\t" // 0

            "movq (%1, %%ebx), %%mm0		\n\t" // block[i]

            "pcmpgtw %%mm0, %%mm1		\n\t" // block[i] <= 0 ? 0xFF : 0x00

            "pxor %%mm1, %%mm0			\n\t"

            "psubw %%mm1, %%mm0			\n\t" // ABS(block[i])

            "movq (%3, %%ebx), %%mm6		\n\t" // bias[0]

            "paddusw %%mm6, %%mm0		\n\t" // ABS(block[i]) + bias[0]

            "movq (%2, %%ebx), %%mm5		\n\t" // qmat[i]

            "pmulhw %%mm5, %%mm0		\n\t" // (ABS(block[i])*qmat[0] + bias[0]*qmat[0])>>16

            "por %%mm0, %%mm4			\n\t"

            "pxor %%mm1, %%mm0			\n\t"

            "psubw %%mm1, %%mm0			\n\t" // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i])

            "movq %%mm0, (%5, %%ebx)		\n\t"

            "pcmpeqw %%mm7, %%mm0		\n\t" // out==0 ? 0xFF : 0x00

            "movq (%4, %%ebx), %%mm1		\n\t"

            "movq %%mm7, (%1, %%ebx)		\n\t" // 0

            "pandn %%mm1, %%mm0			\n\t"

	    PMAXW(%%mm0, %%mm3)

            "addl $8, %%ebx			\n\t"

            " js 1b				\n\t"

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

            "psrlq $32, %%mm3			\n\t"

	    PMAXW(%%mm0, %%mm3)

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

            "psrlq $16, %%mm3			\n\t"

	    PMAXW(%%mm0, %%mm3)

            "movd %%mm3, %%ebx			\n\t"

            "movzbl %%bl, %%ebx			\n\t" // last_non_zero_p1

            "movl %%ebx, (%%ebp)		\n\t"

            "popl %%ebx					\n\t"

            "popl %%ebp					\n\t"

            :

			: "m" (last_non_zero_p1),

              "r" (block+64), "r" (qmat+64), "r" (bias+64),

              "r" (inv_zigzag_direct16+64), "r" (temp_block+64)

        );

        // note the asm is split cuz gcc doesnt like that many operands ...

        asm volatile(

            "movd %1, %%mm1			\n\t" // max_qcoeff

	    SPREADW(%%mm1)

            "psubusw %%mm1, %%mm4		\n\t"

            "packuswb %%mm4, %%mm4		\n\t"

            "movd %%mm4, %0			\n\t" // *overflow

        : "=r" (*overflow)

        : "r" (s->max_qcoeff)

        );

    }

    if(s->mb_intra) block[0]= level;

    else            block[0]= temp_block[0];

    if(s->dsp.idct_permutation_type == FF_SIMPLE_IDCT_PERM){

        if(last_non_zero_p1 <= 1) goto end;

        block[0x08] = temp_block[0x01]; block[0x10] = temp_block[0x08];

        block[0x20] = temp_block[0x10];

        if(last_non_zero_p1 <= 4) goto end;

        block[0x18] = temp_block[0x09]; block[0x04] = temp_block[0x02];

        block[0x09] = temp_block[0x03];

        if(last_non_zero_p1 <= 7) goto end;

        block[0x14] = temp_block[0x0A]; block[0x28] = temp_block[0x11];

        block[0x12] = temp_block[0x18]; block[0x02] = temp_block[0x20];

        if(last_non_zero_p1 <= 11) goto end;

        block[0x1A] = temp_block[0x19]; block[0x24] = temp_block[0x12];

        block[0x19] = temp_block[0x0B]; block[0x01] = temp_block[0x04];

        block[0x0C] = temp_block[0x05];

        if(last_non_zero_p1 <= 16) goto end;

        block[0x11] = temp_block[0x0C]; block[0x29] = temp_block[0x13];

        block[0x16] = temp_block[0x1A]; block[0x0A] = temp_block[0x21];

        block[0x30] = temp_block[0x28]; block[0x22] = temp_block[0x30];

        block[0x38] = temp_block[0x29]; block[0x06] = temp_block[0x22];

        if(last_non_zero_p1 <= 24) goto end;

        block[0x1B] = temp_block[0x1B]; block[0x21] = temp_block[0x14];

        block[0x1C] = temp_block[0x0D]; block[0x05] = temp_block[0x06];

        block[0x0D] = temp_block[0x07]; block[0x15] = temp_block[0x0E];

        block[0x2C] = temp_block[0x15]; block[0x13] = temp_block[0x1C];

        if(last_non_zero_p1 <= 32) goto end;

        block[0x0B] = temp_block[0x23]; block[0x34] = temp_block[0x2A];

        block[0x2A] = temp_block[0x31]; block[0x32] = temp_block[0x38];

        block[0x3A] = temp_block[0x39]; block[0x26] = temp_block[0x32];

        block[0x39] = temp_block[0x2B]; block[0x03] = temp_block[0x24];

        if(last_non_zero_p1 <= 40) goto end;

        block[0x1E] = temp_block[0x1D]; block[0x25] = temp_block[0x16];

        block[0x1D] = temp_block[0x0F]; block[0x2D] = temp_block[0x17];

        block[0x17] = temp_block[0x1E]; block[0x0E] = temp_block[0x25];

        block[0x31] = temp_block[0x2C]; block[0x2B] = temp_block[0x33];

        if(last_non_zero_p1 <= 48) goto end;

        block[0x36] = temp_block[0x3A]; block[0x3B] = temp_block[0x3B];

        block[0x23] = temp_block[0x34]; block[0x3C] = temp_block[0x2D];

        block[0x07] = temp_block[0x26]; block[0x1F] = temp_block[0x1F];

        block[0x0F] = temp_block[0x27]; block[0x35] = temp_block[0x2E];

        if(last_non_zero_p1 <= 56) goto end;

        block[0x2E] = temp_block[0x35]; block[0x33] = temp_block[0x3C];

        block[0x3E] = temp_block[0x3D]; block[0x27] = temp_block[0x36];

        block[0x3D] = temp_block[0x2F]; block[0x2F] = temp_block[0x37];

        block[0x37] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F];

    }else if(s->dsp.idct_permutation_type == FF_LIBMPEG2_IDCT_PERM){

        if(last_non_zero_p1 <= 1) goto end;

        block[0x04] = temp_block[0x01];

        block[0x08] = temp_block[0x08]; block[0x10] = temp_block[0x10];

        if(last_non_zero_p1 <= 4) goto end;

        block[0x0C] = temp_block[0x09]; block[0x01] = temp_block[0x02];

        block[0x05] = temp_block[0x03];

        if(last_non_zero_p1 <= 7) goto end;

        block[0x09] = temp_block[0x0A]; block[0x14] = temp_block[0x11];

        block[0x18] = temp_block[0x18]; block[0x20] = temp_block[0x20];

        if(last_non_zero_p1 <= 11) goto end;

        block[0x1C] = temp_block[0x19];

        block[0x11] = temp_block[0x12]; block[0x0D] = temp_block[0x0B];

        block[0x02] = temp_block[0x04]; block[0x06] = temp_block[0x05];

        if(last_non_zero_p1 <= 16) goto end;

        block[0x0A] = temp_block[0x0C]; block[0x15] = temp_block[0x13];

        block[0x19] = temp_block[0x1A]; block[0x24] = temp_block[0x21];

        block[0x28] = temp_block[0x28]; block[0x30] = temp_block[0x30];

        block[0x2C] = temp_block[0x29]; block[0x21] = temp_block[0x22];

        if(last_non_zero_p1 <= 24) goto end;

        block[0x1D] = temp_block[0x1B]; block[0x12] = temp_block[0x14];

        block[0x0E] = temp_block[0x0D]; block[0x03] = temp_block[0x06];

        block[0x07] = temp_block[0x07]; block[0x0B] = temp_block[0x0E];

        block[0x16] = temp_block[0x15]; block[0x1A] = temp_block[0x1C];

        if(last_non_zero_p1 <= 32) goto end;

        block[0x25] = temp_block[0x23]; block[0x29] = temp_block[0x2A];

        block[0x34] = temp_block[0x31]; block[0x38] = temp_block[0x38];

        block[0x3C] = temp_block[0x39]; block[0x31] = temp_block[0x32];

        block[0x2D] = temp_block[0x2B]; block[0x22] = temp_block[0x24];

        if(last_non_zero_p1 <= 40) goto end;

        block[0x1E] = temp_block[0x1D]; block[0x13] = temp_block[0x16];

        block[0x0F] = temp_block[0x0F]; block[0x17] = temp_block[0x17];

        block[0x1B] = temp_block[0x1E]; block[0x26] = temp_block[0x25];

        block[0x2A] = temp_block[0x2C]; block[0x35] = temp_block[0x33];

        if(last_non_zero_p1 <= 48) goto end;

        block[0x39] = temp_block[0x3A]; block[0x3D] = temp_block[0x3B];

        block[0x32] = temp_block[0x34]; block[0x2E] = temp_block[0x2D];

            block[0x23] = temp_block[0x26]; block[0x1F] = temp_block[0x1F];

        block[0x27] = temp_block[0x27]; block[0x2B] = temp_block[0x2E];

        if(last_non_zero_p1 <= 56) goto end;

        block[0x36] = temp_block[0x35]; block[0x3A] = temp_block[0x3C];

        block[0x3E] = temp_block[0x3D]; block[0x33] = temp_block[0x36];

        block[0x2F] = temp_block[0x2F]; block[0x37] = temp_block[0x37];

        block[0x3B] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F];

    }else{

        if(last_non_zero_p1 <= 1) goto end;

        block[0x01] = temp_block[0x01];

        block[0x08] = temp_block[0x08]; block[0x10] = temp_block[0x10];

        if(last_non_zero_p1 <= 4) goto end;

        block[0x09] = temp_block[0x09]; block[0x02] = temp_block[0x02];

        block[0x03] = temp_block[0x03];

        if(last_non_zero_p1 <= 7) goto end;

        block[0x0A] = temp_block[0x0A]; block[0x11] = temp_block[0x11];

        block[0x18] = temp_block[0x18]; block[0x20] = temp_block[0x20];

        if(last_non_zero_p1 <= 11) goto end;

        block[0x19] = temp_block[0x19];

        block[0x12] = temp_block[0x12]; block[0x0B] = temp_block[0x0B];

        block[0x04] = temp_block[0x04]; block[0x05] = temp_block[0x05];

        if(last_non_zero_p1 <= 16) goto end;

        block[0x0C] = temp_block[0x0C]; block[0x13] = temp_block[0x13];

        block[0x1A] = temp_block[0x1A]; block[0x21] = temp_block[0x21];

        block[0x28] = temp_block[0x28]; block[0x30] = temp_block[0x30];

        block[0x29] = temp_block[0x29]; block[0x22] = temp_block[0x22];

        if(last_non_zero_p1 <= 24) goto end;

        block[0x1B] = temp_block[0x1B]; block[0x14] = temp_block[0x14];

        block[0x0D] = temp_block[0x0D]; block[0x06] = temp_block[0x06];

        block[0x07] = temp_block[0x07]; block[0x0E] = temp_block[0x0E];

        block[0x15] = temp_block[0x15]; block[0x1C] = temp_block[0x1C];

        if(last_non_zero_p1 <= 32) goto end;

        block[0x23] = temp_block[0x23]; block[0x2A] = temp_block[0x2A];

        block[0x31] = temp_block[0x31]; block[0x38] = temp_block[0x38];

        block[0x39] = temp_block[0x39]; block[0x32] = temp_block[0x32];

        block[0x2B] = temp_block[0x2B]; block[0x24] = temp_block[0x24];

        if(last_non_zero_p1 <= 40) goto end;

        block[0x1D] = temp_block[0x1D]; block[0x16] = temp_block[0x16];

        block[0x0F] = temp_block[0x0F]; block[0x17] = temp_block[0x17];

        block[0x1E] = temp_block[0x1E]; block[0x25] = temp_block[0x25];

        block[0x2C] = temp_block[0x2C]; block[0x33] = temp_block[0x33];

        if(last_non_zero_p1 <= 48) goto end;

        block[0x3A] = temp_block[0x3A]; block[0x3B] = temp_block[0x3B];

        block[0x34] = temp_block[0x34]; block[0x2D] = temp_block[0x2D];

        block[0x26] = temp_block[0x26]; block[0x1F] = temp_block[0x1F];

        block[0x27] = temp_block[0x27]; block[0x2E] = temp_block[0x2E];

        if(last_non_zero_p1 <= 56) goto end;

        block[0x35] = temp_block[0x35]; block[0x3C] = temp_block[0x3C];

        block[0x3D] = temp_block[0x3D]; block[0x36] = temp_block[0x36];

        block[0x2F] = temp_block[0x2F]; block[0x37] = temp_block[0x37];

        block[0x3E] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F];

    }

    end:

/*

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

    {

       int j= zigzag_direct_noperm[i];

       block[block_permute_op(j)]= temp_block[j];

    }

*/

    return last_non_zero_p1 - 1;

}


void ff_put_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels,

                             int line_size)

{

    int i;

    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;

    /* read the pixels */

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

        pixels[0] = cm[block[0]];

        pixels[1] = cm[block[1]];

        pixels[2] = cm[block[2]];

        pixels[3] = cm[block[3]];

        pixels[4] = cm[block[4]];

        pixels[5] = cm[block[5]];

        pixels[6] = cm[block[6]];

        pixels[7] = cm[block[7]];

        pixels += line_size;

        block += 8;

    }

}


int has_altivec(void)

{

#ifdef __AMIGAOS4__

    ULONG result = 0;

    extern struct ExecIFace *IExec;

    IExec->GetCPUInfoTags(GCIT_VectorUnit, &result, TAG_DONE);

    if (result == VECTORTYPE_ALTIVEC) return 1;

#elif __APPLE__

    int sels[2] = {CTL_HW, HW_VECTORUNIT};

    int has_vu = 0;

    size_t len = sizeof(has_vu);

    int err;

    err = sysctl(sels, 2, &has_vu, &len, NULL, 0);

    if (err == 0) return (has_vu != 0);

#else

    // since we were compiled for altivec, just assume we have it

    // until someone comes up with a proper way (not involving signal hacks).

#endif /* __AMIGAOS4__ */

}


static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc,

                                AVCodecContext *avctx, const char *args,

                                uint8_t  **poutbuf, int *poutbuf_size,

                                const uint8_t *buf, int      buf_size,

                                int keyframe)

{

    GetBitContext gb;

    PutBitContext pb;

    AACADTSHeaderInfo hdr;

    AACBSFContext *ctx = bsfc->priv_data;

    init_get_bits(&gb, buf, AAC_ADTS_HEADER_SIZE*8);

    *poutbuf = (uint8_t*) buf;

    *poutbuf_size = buf_size;

    if (avctx->extradata)

        if (show_bits(&gb, 12) != 0xfff)

            return 0;

    if (avpriv_aac_parse_header(&gb, &hdr) < 0) {

        av_log(avctx, AV_LOG_ERROR, "Error parsing ADTS frame header!\n");

        return -1;

    }

    if (!hdr.crc_absent && hdr.num_aac_frames > 1) {

        avpriv_report_missing_feature(avctx,

                                      "Multiple RDBs per frame with CRC");

        return AVERROR_PATCHWELCOME;

    }

    buf      += AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent;

    buf_size -= AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent;

    if (!ctx->first_frame_done) {

        int            pce_size = 0;

        uint8_t        pce_data[MAX_PCE_SIZE];

        if (!hdr.chan_config) {

            init_get_bits(&gb, buf, buf_size * 8);

            if (get_bits(&gb, 3) != 5) {

                avpriv_report_missing_feature(avctx,

                                              "PCE-based channel configuration "

                                              "without PCE as first syntax "

                                              "element");

                return AVERROR_PATCHWELCOME;

            }

            init_put_bits(&pb, pce_data, MAX_PCE_SIZE);

            pce_size = avpriv_copy_pce_data(&pb, &gb)/8;

            flush_put_bits(&pb);

            buf_size -= get_bits_count(&gb)/8;

            buf      += get_bits_count(&gb)/8;

        }

        avctx->extradata_size = 2 + pce_size;

        avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);

        init_put_bits(&pb, avctx->extradata, avctx->extradata_size);

        put_bits(&pb, 5, hdr.object_type);

        put_bits(&pb, 4, hdr.sampling_index);

        put_bits(&pb, 4, hdr.chan_config);

        put_bits(&pb, 1, 0); //frame length - 1024 samples

        put_bits(&pb, 1, 0); //does not depend on core coder

        put_bits(&pb, 1, 0); //is not extension

        flush_put_bits(&pb);

        if (pce_size) {

            memcpy(avctx->extradata + 2, pce_data, pce_size);

        }

        ctx->first_frame_done = 1;

    }

    *poutbuf = (uint8_t*) buf;

    *poutbuf_size = buf_size;

    return 0;

}


static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *buf_end){

    unsigned char *frame0_end = s->last_frame.data[0] + s->avctx->width*s->last_frame.linesize[0];

    int num_mvs;

    int num_blocks_raw;

    int num_blocks_packed;

    int vector_bits;

    int i,j,x,y;

    GetBitContext gb;

    int mvbits;

    const unsigned char *blocks_raw;

    if(buf+12>buf_end)

        return -1;

    num_mvs           = AV_RL16(&buf[0]);

    num_blocks_raw    = AV_RL16(&buf[2]);

    num_blocks_packed = AV_RL16(&buf[4]);

    vector_bits       = AV_RL16(&buf[6]);

    buf += 12;

    /* allocate codebook buffers as neccessary */

    if (num_mvs > s->num_mvs) {

        s->mv_codebook = av_realloc(s->mv_codebook, num_mvs*2*sizeof(int));

        s->num_mvs = num_mvs;

    }

    if (num_blocks_packed > s->num_blocks_packed) {

        s->block_codebook = av_realloc(s->block_codebook, num_blocks_packed*16*sizeof(unsigned char));

        s->num_blocks_packed = num_blocks_packed;

    }

    /* read motion vectors */

    mvbits = (num_mvs*2*10+31) & ~31;

    if (buf+(mvbits>>3)+16*num_blocks_raw+8*num_blocks_packed>buf_end)

        return -1;

    init_get_bits(&gb, buf, mvbits);

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

        s->mv_codebook[i][0] = get_sbits(&gb, 10);

        s->mv_codebook[i][1] = get_sbits(&gb, 10);

    }

    buf += mvbits>>3;

    /* note ptr to uncompressed blocks */

    blocks_raw = buf;

    buf += num_blocks_raw*16;

    /* read compressed blocks */

    init_get_bits(&gb, buf, (buf_end-buf)<<3);

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

        int tmp[4];

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

            tmp[j] = get_bits(&gb, 8);

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

            s->block_codebook[i][15-j] = tmp[get_bits(&gb, 2)];

    }

    if (get_bits_left(&gb) < vector_bits *

        (s->avctx->height/4) * (s->avctx->width/4))

        return -1;

    /* read vectors and build frame */

    for(y=0; y<s->avctx->height/4; y++)

    for(x=0; x<s->avctx->width/4; x++) {

        unsigned int vector = get_bits(&gb, vector_bits);

        const unsigned char *src;

        int src_stride;

        if (vector < num_mvs) {

            src = s->last_frame.data[0] +

                  (y*4 + s->mv_codebook[vector][1])*s->last_frame.linesize[0] +

                   x*4 + s->mv_codebook[vector][0];

            src_stride = s->last_frame.linesize[0];

            if (src+3*src_stride+3>=frame0_end)

                continue;

        }else{

            int offset = vector - num_mvs;

            if (offset<num_blocks_raw)

                src = blocks_raw + 16*offset;

            else if (offset-num_blocks_raw<num_blocks_packed)

                src = s->block_codebook[offset-num_blocks_raw];

            else

                continue;

            src_stride = 4;

        }

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

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

            s->frame.data[0][ (y*4+j)*s->frame.linesize[0] + (x*4+i)  ] =

               src[j*src_stride + i];

    }

    return 0;

}


static void generic_loader_realize(DeviceState *dev, Error **errp)

{

    GenericLoaderState *s = GENERIC_LOADER(dev);

    hwaddr entry;

    int big_endian;

    int size = 0;

    s->set_pc = false;

    /* Perform some error checking on the user's options */

    if (s->data || s->data_len  || s->data_be) {

        /* User is loading memory values */

        if (s->file) {

            error_setg(errp, "Specifying a file is not supported when loading "

                       "memory values");

            return;

        } else if (s->force_raw) {

            error_setg(errp, "Specifying force-raw is not supported when "

                       "loading memory values");

            return;

        } else if (!s->data_len) {

            /* We can't check for !data here as a value of 0 is still valid. */

            error_setg(errp, "Both data and data-len must be specified");

            return;

        } else if (s->data_len > 8) {

            error_setg(errp, "data-len cannot be greater then 8 bytes");

            return;

        }

    } else if (s->file || s->force_raw)  {

        /* User is loading an image */

        if (s->data || s->data_len || s->data_be) {

            error_setg(errp, "data can not be specified when loading an "

                       "image");

            return;

        }

        /* The user specified a file, only set the PC if they also specified

         * a CPU to use.

         */

        if (s->cpu_num != CPU_NONE) {

            s->set_pc = true;

        }

    } else if (s->addr) {

        /* User is setting the PC */

        if (s->data || s->data_len || s->data_be) {

            error_setg(errp, "data can not be specified when setting a "

                       "program counter");

            return;

        } else if (!s->cpu_num) {

            error_setg(errp, "cpu_num must be specified when setting a "

                       "program counter");

            return;

        }

        s->set_pc = true;

    } else {

        /* Did the user specify anything? */

        error_setg(errp, "please include valid arguments");

        return;

    }

    qemu_register_reset(generic_loader_reset, dev);

    if (s->cpu_num != CPU_NONE) {

        s->cpu = qemu_get_cpu(s->cpu_num);

        if (!s->cpu) {

            error_setg(errp, "Specified boot CPU#%d is nonexistent",

                       s->cpu_num);

            return;

        }

    } else {

        s->cpu = first_cpu;

    }

#ifdef TARGET_WORDS_BIGENDIAN

    big_endian = 1;

#else

    big_endian = 0;

#endif

    if (s->file) {

        if (!s->force_raw) {

            size = load_elf_as(s->file, NULL, NULL, &entry, NULL, NULL,

                               big_endian, 0, 0, 0, s->cpu->as);

            if (size < 0) {

                size = load_uimage_as(s->file, &entry, NULL, NULL, NULL, NULL,

                                      s->cpu->as);

            }

        }

        if (size < 0 || s->force_raw) {

            /* Default to the maximum size being the machine's ram size */

            size = load_image_targphys_as(s->file, s->addr, ram_size,

                                          s->cpu->as);

        } else {

            s->addr = entry;

        }

        if (size < 0) {

            error_setg(errp, "Cannot load specified image %s", s->file);

            return;

        }

    }

    /* Convert the data endiannes */

    if (s->data_be) {

        s->data = cpu_to_be64(s->data);

    } else {

        s->data = cpu_to_le64(s->data);

    }

}


static inline void RENAME(nvXXtoUV)(uint8_t *dst1, uint8_t *dst2,

                                    const uint8_t *src, long width)

{

#if COMPILE_TEMPLATE_MMX

    __asm__ volatile(

        "movq "MANGLE(bm01010101)", %%mm4           \n\t"

        "mov                    %0, %%"REG_a"       \n\t"

        "1:                                         \n\t"

        "movq    (%1, %%"REG_a",2), %%mm0           \n\t"

        "movq   8(%1, %%"REG_a",2), %%mm1           \n\t"

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

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

        "pand                %%mm4, %%mm0           \n\t"

        "pand                %%mm4, %%mm1           \n\t"

        "psrlw                  $8, %%mm2           \n\t"

        "psrlw                  $8, %%mm3           \n\t"

        "packuswb            %%mm1, %%mm0           \n\t"

        "packuswb            %%mm3, %%mm2           \n\t"

        "movq                %%mm0, (%2, %%"REG_a") \n\t"

        "movq                %%mm2, (%3, %%"REG_a") \n\t"

        "add                    $8, %%"REG_a"       \n\t"

        " js                    1b                  \n\t"

        : : "g" ((x86_reg)-width), "r" (src+width*2), "r" (dst1+width), "r" (dst2+width)

        : "%"REG_a

    );

#else

    int i;

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

        dst1[i] = src[2*i+0];

        dst2[i] = src[2*i+1];

    }

#endif

}


static int mpc7_decode_init(AVCodecContext * avctx)

{

    int i, j;

    MPCContext *c = avctx->priv_data;

    GetBitContext gb;

    uint8_t buf[16];

    static int vlc_inited = 0;

    if(avctx->extradata_size < 16){

        av_log(avctx, AV_LOG_ERROR, "Too small extradata size (%i)!\n", avctx->extradata_size);

        return -1;

    }

    memset(c->oldDSCF, 0, sizeof(c->oldDSCF));

    av_init_random(0xDEADBEEF, &c->rnd);

    dsputil_init(&c->dsp, avctx);

    c->dsp.bswap_buf((uint32_t*)buf, (const uint32_t*)avctx->extradata, 4);

    ff_mpc_init();

    init_get_bits(&gb, buf, 128);

    c->IS = get_bits1(&gb);

    c->MSS = get_bits1(&gb);

    c->maxbands = get_bits(&gb, 6);

    if(c->maxbands >= BANDS){

        av_log(avctx, AV_LOG_ERROR, "Too many bands: %i\n", c->maxbands);

        return -1;

    }

    skip_bits(&gb, 88);

    c->gapless = get_bits1(&gb);

    c->lastframelen = get_bits(&gb, 11);

    av_log(avctx, AV_LOG_DEBUG, "IS: %d, MSS: %d, TG: %d, LFL: %d, bands: %d\n",

            c->IS, c->MSS, c->gapless, c->lastframelen, c->maxbands);

    c->frames_to_skip = 0;

    if(vlc_inited) return 0;

    av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n");

    if(init_vlc(&scfi_vlc, MPC7_SCFI_BITS, MPC7_SCFI_SIZE,

                &mpc7_scfi[1], 2, 1,

                &mpc7_scfi[0], 2, 1, INIT_VLC_USE_STATIC)){

        av_log(avctx, AV_LOG_ERROR, "Cannot init SCFI VLC\n");

        return -1;

    }

    if(init_vlc(&dscf_vlc, MPC7_DSCF_BITS, MPC7_DSCF_SIZE,

                &mpc7_dscf[1], 2, 1,

                &mpc7_dscf[0], 2, 1, INIT_VLC_USE_STATIC)){

        av_log(avctx, AV_LOG_ERROR, "Cannot init DSCF VLC\n");

        return -1;

    }

    if(init_vlc(&hdr_vlc, MPC7_HDR_BITS, MPC7_HDR_SIZE,

                &mpc7_hdr[1], 2, 1,

                &mpc7_hdr[0], 2, 1, INIT_VLC_USE_STATIC)){

        av_log(avctx, AV_LOG_ERROR, "Cannot init HDR VLC\n");

        return -1;

    }

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

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

            if(init_vlc(&quant_vlc[i][j], 9, mpc7_quant_vlc_sizes[i],

                        &mpc7_quant_vlc[i][j][1], 4, 2,

                        &mpc7_quant_vlc[i][j][0], 4, 2, INIT_VLC_USE_STATIC)){

                av_log(avctx, AV_LOG_ERROR, "Cannot init QUANT VLC %i,%i\n",i,j);

                return -1;

            }

        }

    }

    vlc_inited = 1;

    return 0;

}


void ff_vp3_idct_altivec(DCTELEM block[64])

{

    IDCT_START

    IDCT_1D(NOP, NOP)

    TRANSPOSE8(b0, b1, b2, b3, b4, b5, b6, b7);

    IDCT_1D(ADD8, SHIFT4)

    vec_st(b0, 0x00, block);

    vec_st(b1, 0x10, block);

    vec_st(b2, 0x20, block);

    vec_st(b3, 0x30, block);

    vec_st(b4, 0x40, block);

    vec_st(b5, 0x50, block);

    vec_st(b6, 0x60, block);

    vec_st(b7, 0x70, block);

}


static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)

{

    AVStream *st;

    MOVStreamContext *sc;

    unsigned int i, j, entries, ctts_count = 0;

    if (c->fc->nb_streams < 1)

        return 0;

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

    sc = st->priv_data;

    avio_r8(pb); /* version */

    avio_rb24(pb); /* flags */

    entries = avio_rb32(pb);

    av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);

    if (!entries)

        return 0;

    if (entries >= UINT_MAX / sizeof(*sc->ctts_data))

        return AVERROR_INVALIDDATA;

    av_freep(&sc->ctts_data);

    sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));

    if (!sc->ctts_data)

        return AVERROR(ENOMEM);

    for (i = 0; i < entries && !pb->eof_reached; i++) {

        int count    =avio_rb32(pb);

        int duration =avio_rb32(pb);

        if (count <= 0) {

            av_log(c->fc, AV_LOG_TRACE,

                   "ignoring CTTS entry with count=%d duration=%d\n",

                   count, duration);

            continue;

        }

        /* Expand entries such that we have a 1-1 mapping with samples. */

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

            add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size, 1, duration);

        av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",

                count, duration);

        if (FFNABS(duration) < -(1<<28) && i+2<entries) {

            av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");

            av_freep(&sc->ctts_data);

            sc->ctts_count = 0;

            return 0;

        }

        if (i+2<entries)

            mov_update_dts_shift(sc, duration);

    }

    sc->ctts_count = ctts_count;

    if (pb->eof_reached)

        return AVERROR_EOF;

    av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);

    return 0;

}


static void gen_mfsrin(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);

#else

    TCGv t0;

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);

        return;

    }

    t0 = tcg_temp_new();

    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);

    tcg_gen_andi_tl(t0, t0, 0xF);

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

    tcg_temp_free(t0);

#endif

}


void qemu_sem_wait(QemuSemaphore *sem)

{

#if defined(__APPLE__) || defined(__NetBSD__)

    pthread_mutex_lock(&sem->lock);

    --sem->count;

    while (sem->count < 0) {

        pthread_cond_wait(&sem->cond, &sem->lock);

    }

    pthread_mutex_unlock(&sem->lock);

#else

    int rc;

    do {

        rc = sem_wait(&sem->sem);

    } while (rc == -1 && errno == EINTR);

    if (rc < 0) {

        error_exit(errno, __func__);

    }

#endif

}


static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags)

{

    int isv34, tlen, unsync;

    char tag[5];

    int64_t next, end = avio_tell(s->pb) + len;

    int taghdrlen;

    const char *reason = NULL;

    AVIOContext pb;

    unsigned char *buffer = NULL;

    int buffer_size = 0;

    switch (version) {

    case 2:

        if (flags & 0x40) {

            reason = "compression";

            goto error;

        }

        isv34 = 0;

        taghdrlen = 6;

        break;

    case 3:

    case 4:

        isv34 = 1;

        taghdrlen = 10;

        break;

    default:

        reason = "version";

        goto error;

    }

    unsync = flags & 0x80;

    if (isv34 && flags & 0x40) /* Extended header present, just skip over it */

        avio_skip(s->pb, get_size(s->pb, 4));

    while (len >= taghdrlen) {

        unsigned int tflags;

        int tunsync = 0;

        if (isv34) {

            avio_read(s->pb, tag, 4);

            tag[4] = 0;

            if(version==3){

                tlen = avio_rb32(s->pb);

            }else

                tlen = get_size(s->pb, 4);

            tflags = avio_rb16(s->pb);

            tunsync = tflags & ID3v2_FLAG_UNSYNCH;

        } else {

            avio_read(s->pb, tag, 3);

            tag[3] = 0;

            tlen = avio_rb24(s->pb);

        }

        len -= taghdrlen + tlen;

        if (len < 0)

            break;

        next = avio_tell(s->pb) + tlen;

        if (tflags & ID3v2_FLAG_DATALEN) {

            avio_rb32(s->pb);

            tlen -= 4;

        }

        if (tflags & (ID3v2_FLAG_ENCRYPTION | ID3v2_FLAG_COMPRESSION)) {

            av_log(s, AV_LOG_WARNING, "Skipping encrypted/compressed ID3v2 frame %s.\n", tag);

            avio_skip(s->pb, tlen);

        } else if (tag[0] == 'T') {

            if (unsync || tunsync) {

                int i, j;

                av_fast_malloc(&buffer, &buffer_size, tlen);

                for (i = 0, j = 0; i < tlen; i++, j++) {

                    buffer[j] = avio_r8(s->pb);

                    if (j > 0 && !buffer[j] && buffer[j - 1] == 0xff) {

                        /* Unsynchronised byte, skip it */

                        j--;

                    }

                }

                ffio_init_context(&pb, buffer, j, 0, NULL, NULL, NULL, NULL);

                read_ttag(s, &pb, j, tag);

            } else {

                read_ttag(s, s->pb, tlen, tag);

            }

        }

        else if (!tag[0]) {

            if (tag[1])

                av_log(s, AV_LOG_WARNING, "invalid frame id, assuming padding");

            avio_skip(s->pb, tlen);

            break;

        }

        /* Skip to end of tag */

        avio_seek(s->pb, next, SEEK_SET);

    }

    if (version == 4 && flags & 0x10) /* Footer preset, always 10 bytes, skip over it */

        end += 10;

  error:

    if (reason)

        av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n", version, reason);

    avio_seek(s->pb, end, SEEK_SET);

    av_free(buffer);

    return;

}


void palette8torgb24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)

{

	long i;

/*

	writes 1 byte o much and might cause alignment issues on some architectures?

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

		((unsigned *)(&dst[i*3])) = ((unsigned *)palette)[ src[i] ];

*/

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

	{

		//FIXME slow?

		dst[0]= palette[ src[i]*4+2 ];

		dst[1]= palette[ src[i]*4+1 ];

		dst[2]= palette[ src[i]*4+0 ];

		dst+= 3;

	}

}


static int m25p80_init(SSISlave *ss)

{

    DriveInfo *dinfo;

    Flash *s = M25P80(ss);

    M25P80Class *mc = M25P80_GET_CLASS(s);

    s->pi = mc->pi;

    s->size = s->pi->sector_size * s->pi->n_sectors;

    s->dirty_page = -1;

    s->storage = blk_blockalign(s->blk, s->size);

    /* FIXME use a qdev drive property instead of drive_get_next() */

    dinfo = drive_get_next(IF_MTD);

    if (dinfo) {

        DB_PRINT_L(0, "Binding to IF_MTD drive\n");

        s->blk = blk_by_legacy_dinfo(dinfo);

        blk_attach_dev_nofail(s->blk, s);

        /* FIXME: Move to late init */

        if (blk_read(s->blk, 0, s->storage,

                     DIV_ROUND_UP(s->size, BDRV_SECTOR_SIZE))) {

            fprintf(stderr, "Failed to initialize SPI flash!\n");

            return 1;

        }

    } else {

        DB_PRINT_L(0, "No BDRV - binding to RAM\n");

        memset(s->storage, 0xFF, s->size);

    }

    return 0;

}


void visit_start_list(Visitor *v, const char *name, GenericList **list,

                      size_t size, Error **errp)

{

    Error *err = NULL;

    assert(!list || size >= sizeof(GenericList));

    v->start_list(v, name, list, size, &err);

    if (list && v->type == VISITOR_INPUT) {

        assert(!(err && *list));

    }

    error_propagate(errp, err);

}


static unsigned __stdcall win32_start_routine(void *arg)

{

    struct QemuThreadData data = *(struct QemuThreadData *) arg;

    QemuThread *thread = data.thread;

    free(arg);

    TlsSetValue(qemu_thread_tls_index, thread);

    /*

     * Use DuplicateHandle instead of assigning thread->thread in the

     * creating thread to avoid races.  It's simpler this way than with

     * synchronization.

     */

    DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),

                    GetCurrentProcess(), &thread->thread,

                    0, FALSE, DUPLICATE_SAME_ACCESS);

    qemu_thread_exit(data.start_routine(data.arg));

    abort();

}


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

{

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

    MOVStreamContext *sc = st->priv_data;

    unsigned int i, entries;

    get_byte(pb); /* version */

    get_be24(pb); /* flags */

    entries = get_be32(pb);

    dprintf(c->fc, "keyframe_count = %d\n", entries);

    if(entries >= UINT_MAX / sizeof(int))

        return -1;

    sc->keyframes = av_malloc(entries * sizeof(int));

    if (!sc->keyframes)

        return AVERROR(ENOMEM);

    sc->keyframe_count = entries;

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

        sc->keyframes[i] = get_be32(pb);

        //dprintf(c->fc, "keyframes[]=%d\n", sc->keyframes[i]);

    }

    return 0;

}


static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int band,

                           float *bits, float lambda)

{

    int i, b = 0;

    uint32_t cm[2] = { (1 << f->blocks) - 1, (1 << f->blocks) - 1 };

    const int band_size = ff_celt_freq_range[band] << f->size;

    float buf[176 * 2], lowband_scratch[176], norm1[176], norm2[176];

    float dist, cost, err_x = 0.0f, err_y = 0.0f;

    float *X = buf;

    float *X_orig = f->block[0].coeffs + (ff_celt_freq_bands[band] << f->size);

    float *Y = (f->channels == 2) ? &buf[176] : NULL;

    float *Y_orig = f->block[1].coeffs + (ff_celt_freq_bands[band] << f->size);

    OPUS_RC_CHECKPOINT_SPAWN(rc);

    memcpy(X, X_orig, band_size*sizeof(float));

    if (Y)

        memcpy(Y, Y_orig, band_size*sizeof(float));

    f->remaining2 = ((f->framebits << 3) - f->anticollapse_needed) - opus_rc_tell_frac(rc) - 1;

    if (band <= f->coded_bands - 1) {

        int curr_balance = f->remaining / FFMIN(3, f->coded_bands - band);

        b = av_clip_uintp2(FFMIN(f->remaining2 + 1, f->pulses[band] + curr_balance), 14);

    }

    if (f->dual_stereo) {

        pvq->encode_band(pvq, f, rc, band, X, NULL, band_size, b / 2, f->blocks, NULL,

                         f->size, norm1, 0, 1.0f, lowband_scratch, cm[0]);

        pvq->encode_band(pvq, f, rc, band, Y, NULL, band_size, b / 2, f->blocks, NULL,

                         f->size, norm2, 0, 1.0f, lowband_scratch, cm[1]);

    } else {

        pvq->encode_band(pvq, f, rc, band, X, Y, band_size, b, f->blocks, NULL, f->size,

                         norm1, 0, 1.0f, lowband_scratch, cm[0] | cm[1]);

    }

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

        err_x += (X[i] - X_orig[i])*(X[i] - X_orig[i]);

        err_y += (Y[i] - Y_orig[i])*(Y[i] - Y_orig[i]);

    }

    dist = sqrtf(err_x) + sqrtf(err_y);

    cost = OPUS_RC_CHECKPOINT_BITS(rc)/8.0f;

    *bits += cost;

    OPUS_RC_CHECKPOINT_ROLLBACK(rc);

    return lambda*dist*cost;

}


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

{

    AVStream *st = s->streams[0]; // video stream

    R3DContext *r3d = s->priv_data;

    int frame_num;

    if (!st->codec->time_base.num || !st->time_base.den)

        return -1;

    frame_num = sample_time*st->codec->time_base.den/

        ((int64_t)st->codec->time_base.num*st->time_base.den);

    av_dlog(s, "seek frame num %d timestamp %"PRId64"\n",

            frame_num, sample_time);

    if (frame_num < r3d->video_offsets_count) {

        avio_seek(s->pb, r3d->video_offsets_count, SEEK_SET);

    } else {

        av_log(s, AV_LOG_ERROR, "could not seek to frame %d\n", frame_num);

        return -1;

    }

    return 0;

}


m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base,

                       uint32_t io_base, uint16_t size,

                       int type)

{

    DeviceState *dev;

    SysBusDevice *s;

    M48t59SysBusState *d;

    dev = qdev_create(NULL, "m48t59");

    qdev_prop_set_uint32(dev, "type", type);

    qdev_prop_set_uint32(dev, "size", size);

    qdev_prop_set_uint32(dev, "io_base", io_base);

    qdev_init(dev);

    s = sysbus_from_qdev(dev);

    sysbus_connect_irq(s, 0, IRQ);

    if (io_base != 0) {

        register_ioport_read(io_base, 0x04, 1, NVRAM_readb, s);

        register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, s);

    }

    if (mem_base != 0) {

        sysbus_mmio_map(s, 0, mem_base);

    }

    d = FROM_SYSBUS(M48t59SysBusState, s);

    return &d->state;

}


static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,

                               const int data_size, AVCodecContext *avctx)

{

    int hdr_size, width, height, flags;

    int version;

    const uint8_t *ptr;

    hdr_size = AV_RB16(buf);

    av_dlog(avctx, "header size %d\n", hdr_size);

    if (hdr_size > data_size) {

        av_log(avctx, AV_LOG_ERROR, "error, wrong header size\n");

    version = AV_RB16(buf + 2);

    av_dlog(avctx, "%.4s version %d\n", buf+4, version);

    if (version > 1) {

        av_log(avctx, AV_LOG_ERROR, "unsupported version: %d\n", version);

    width  = AV_RB16(buf + 8);

    height = AV_RB16(buf + 10);

    if (width != avctx->width || height != avctx->height) {

        av_log(avctx, AV_LOG_ERROR, "picture resolution change: %dx%d -> %dx%d\n",

               avctx->width, avctx->height, width, height);

    ctx->frame_type = (buf[12] >> 2) & 3;

    av_dlog(avctx, "frame type %d\n", ctx->frame_type);

    if (ctx->frame_type == 0) {

        ctx->scan = ctx->progressive_scan; // permuted

    } else {

        ctx->scan = ctx->interlaced_scan; // permuted

        ctx->frame.interlaced_frame = 1;

        ctx->frame.top_field_first = ctx->frame_type == 1;

    avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV422P10;

    ptr   = buf + 20;

    flags = buf[19];

    av_dlog(avctx, "flags %x\n", flags);

    if (flags & 2) {

        permute(ctx->qmat_luma, ctx->prodsp.idct_permutation, ptr);

        ptr += 64;

    } else {

        memset(ctx->qmat_luma, 4, 64);

    if (flags & 1) {

        permute(ctx->qmat_chroma, ctx->prodsp.idct_permutation, ptr);

    } else {

        memset(ctx->qmat_chroma, 4, 64);

    return hdr_size;


static inline int GetCode(GifState * s)

{

    int c, sizbuf;

    uint8_t *ptr;

    while (s->bbits < s->cursize) {

        ptr = s->pbuf;

        if (ptr >= s->ebuf) {

            if (!s->eob_reached) {

                sizbuf = get_byte(s->f);

                s->ebuf = s->buf + sizbuf;

                s->pbuf = s->buf;

                if (sizbuf > 0) {

                    get_buffer(s->f, s->buf, sizbuf);

                } else {

                    s->eob_reached = 1;

                }

            }

            ptr = s->pbuf;

        }

        s->bbuf |= ptr[0] << s->bbits;

        ptr++;

        s->pbuf = ptr;

        s->bbits += 8;

    }

    c = s->bbuf & s->curmask;

    s->bbuf >>= s->cursize;

    s->bbits -= s->cursize;

    return c;

}


static void filter(SPPContext *p, uint8_t *dst, uint8_t *src,

                   int dst_linesize, int src_linesize, int width, int height,

                   const uint8_t *qp_table, int qp_stride, int is_luma, int sample_bytes)

{

    int x, y, i;

    const int count = 1 << p->log2_count;

    const int linesize = is_luma ? p->temp_linesize : FFALIGN(width+16, 16);

    DECLARE_ALIGNED(16, uint64_t, block_align)[32];

    int16_t *block  = (int16_t *)block_align;

    int16_t *block2 = (int16_t *)(block_align + 16);

    uint16_t *psrc16 = (uint16_t*)p->src;

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

        int index = 8 + 8*linesize + y*linesize;

        memcpy(p->src + index*sample_bytes, src + y*src_linesize, width*sample_bytes);

        if (sample_bytes == 1) {

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

                p->src[index         - x - 1] = p->src[index +         x    ];

                p->src[index + width + x    ] = p->src[index + width - x - 1];

            }

        } else {

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

                psrc16[index         - x - 1] = psrc16[index +         x    ];

                psrc16[index + width + x    ] = psrc16[index + width - x - 1];

            }

        }

    }

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

        memcpy(p->src + (       7-y)*linesize * sample_bytes, p->src + (       y+8)*linesize * sample_bytes, linesize * sample_bytes);

        memcpy(p->src + (height+8+y)*linesize * sample_bytes, p->src + (height-y+7)*linesize * sample_bytes, linesize * sample_bytes);

    }

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

        memset(p->temp + (8 + y) * linesize, 0, 8 * linesize * sizeof(*p->temp));

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

            int qp;

            if (p->qp) {

                qp = p->qp;

            } else{

                const int qps = 3 + is_luma;

                qp = qp_table[(FFMIN(x, width - 1) >> qps) + (FFMIN(y, height - 1) >> qps) * qp_stride];

                qp = FFMAX(1, norm_qscale(qp, p->qscale_type));

            }

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

                const int x1 = x + offset[i + count - 1][0];

                const int y1 = y + offset[i + count - 1][1];

                const int index = x1 + y1*linesize;

                p->dct->get_pixels(block, p->src + sample_bytes*index, sample_bytes*linesize);

                p->dct->fdct(block);

                p->requantize(block2, block, qp, p->dct->idct_permutation);

                p->dct->idct(block2);

                add_block(p->temp + index, linesize, block2);

            }

        }

        if (y) {

            if (sample_bytes == 1) {

                p->store_slice(dst + (y - 8) * dst_linesize, p->temp + 8 + y*linesize,

                               dst_linesize, linesize, width,

                               FFMIN(8, height + 8 - y), MAX_LEVEL - p->log2_count,

                               ldither);

            } else {

                store_slice16_c((uint16_t*)(dst + (y - 8) * dst_linesize), p->temp + 8 + y*linesize,

                                dst_linesize/2, linesize, width,

                                FFMIN(8, height + 8 - y), MAX_LEVEL - p->log2_count,

                                ldither);

            }

        }

    }

}


static int vp8_alloc_frame(VP8Context *s, AVFrame *f)

{

    int ret;

    if ((ret = ff_thread_get_buffer(s->avctx, f)) < 0)

        return ret;

    if (!s->maps_are_invalid && s->num_maps_to_be_freed) {

        f->ref_index[0] = s->segmentation_maps[--s->num_maps_to_be_freed];

    } else if (!(f->ref_index[0] = av_mallocz(s->mb_width * s->mb_height))) {

        ff_thread_release_buffer(s->avctx, f);

        return AVERROR(ENOMEM);

    }

    return 0;

}


static int64_t read_ts(const char *s)

{

    int hh, mm, ss, ms;

    if (sscanf(s, "%u:%u:%u.%u", &hh, &mm, &ss, &ms) == 4) return (hh*3600 + mm*60 + ss) * 1000 + ms;

    if (sscanf(s,    "%u:%u.%u",      &mm, &ss, &ms) == 3) return (          mm*60 + ss) * 1000 + ms;

    return AV_NOPTS_VALUE;

}


static void i82374_init(I82374State *s)

{

    DMA_init(1, NULL);

    memset(s->commands, 0, sizeof(s->commands));

}


static void qxl_destroy_primary(PCIQXLDevice *d)

{

    if (d->mode == QXL_MODE_UNDEFINED) {

        return;

    }

    dprint(d, 1, "%s\n", __FUNCTION__);

    d->mode = QXL_MODE_UNDEFINED;

    d->ssd.worker->destroy_primary_surface(d->ssd.worker, 0);

}


void isa_ne2000_init(int base, int irq, NICInfo *nd)

{

    ISADevice *dev;

    qemu_check_nic_model(nd, "ne2k_isa");

    dev = isa_create("ne2k_isa");

    dev->qdev.nd = nd; /* hack alert */

    qdev_prop_set_uint32(&dev->qdev, "iobase", base);

    qdev_prop_set_uint32(&dev->qdev, "irq",    irq);

    qdev_init(&dev->qdev);

}


static int allocate_buffers(ShortenContext *s)

{

    int i, chan, err;

    for (chan = 0; chan < s->channels; chan++) {

        if (FFMAX(1, s->nmean) >= UINT_MAX / sizeof(int32_t)) {

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

            return AVERROR_INVALIDDATA;

        }

        if (s->blocksize + s->nwrap >= UINT_MAX / sizeof(int32_t) ||

            s->blocksize + s->nwrap <= (unsigned)s->nwrap) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "s->blocksize + s->nwrap too large\n");

            return AVERROR_INVALIDDATA;

        }

        if ((err = av_reallocp_array(&s->offset[chan],

                               sizeof(int32_t),

                               FFMAX(1, s->nmean))) < 0)

            return err;

        if ((err = av_reallocp_array(&s->decoded_base[chan], (s->blocksize + s->nwrap),

                               sizeof(s->decoded_base[0][0]))) < 0)

            return err;

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

            s->decoded_base[chan][i] = 0;

        s->decoded[chan] = s->decoded_base[chan] + s->nwrap;

    }

    if ((err = av_reallocp_array(&s->coeffs, s->nwrap, sizeof(*s->coeffs))) < 0)

        return err;

    return 0;

}


static av_always_inline int rv40_loop_filter_strength(uint8_t *src,

                                                      int step, int stride,

                                                      int beta, int beta2,

                                                      int edge,

                                                      int *p1, int *q1)

{

    int sum_p1p0 = 0, sum_q1q0 = 0, sum_p1p2 = 0, sum_q1q2 = 0;

    int strong0 = 0, strong1 = 0;

    uint8_t *ptr;

    int i;

    for (i = 0, ptr = src; i < 4; i++, ptr += stride) {

        sum_p1p0 += ptr[-2*step] - ptr[-1*step];

        sum_q1q0 += ptr[ 1*step] - ptr[ 0*step];

    }

    *p1 = FFABS(sum_p1p0) < (beta << 2);

    *q1 = FFABS(sum_q1q0) < (beta << 2);

    if(!*p1 && !*q1)

        return 0;

    if (!edge)

        return 0;

    for (i = 0, ptr = src; i < 4; i++, ptr += stride) {

        sum_p1p2 += ptr[-2*step] - ptr[-3*step];

        sum_q1q2 += ptr[ 1*step] - ptr[ 2*step];

    }

    strong0 = *p1 && (FFABS(sum_p1p2) < beta2);

    strong1 = *q1 && (FFABS(sum_q1q2) < beta2);

    return strong0 && strong1;

}


static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce,

                                     int win, int group_len, const float lambda)

{

    BandCodingPath path[120][CB_TOT_ALL];

    int w, swb, cb, start, size;

    int i, j;

    const int max_sfb  = sce->ics.max_sfb;

    const int run_bits = sce->ics.num_windows == 1 ? 5 : 3;

    const int run_esc  = (1 << run_bits) - 1;

    int idx, ppos, count;

    int stackrun[120], stackcb[120], stack_len;

    float next_minrd = INFINITY;

    int next_mincb = 0;

    abs_pow34_v(s->scoefs, sce->coeffs, 1024);

    start = win*128;

    for (cb = 0; cb < CB_TOT_ALL; cb++) {

        path[0][cb].cost     = 0.0f;

        path[0][cb].prev_idx = -1;

        path[0][cb].run      = 0;

    }

    for (swb = 0; swb < max_sfb; swb++) {

        size = sce->ics.swb_sizes[swb];

        if (sce->zeroes[win*16 + swb]) {

            for (cb = 0; cb < CB_TOT_ALL; cb++) {

                path[swb+1][cb].prev_idx = cb;

                path[swb+1][cb].cost     = path[swb][cb].cost;

                path[swb+1][cb].run      = path[swb][cb].run + 1;

            }

        } else {

            float minrd = next_minrd;

            int mincb = next_mincb;

            next_minrd = INFINITY;

            next_mincb = 0;

            for (cb = 0; cb < CB_TOT_ALL; cb++) {

                float cost_stay_here, cost_get_here;

                float rd = 0.0f;

                if (cb >= 12 && sce->band_type[win*16+swb] < aac_cb_out_map[cb] ||

                    cb  < aac_cb_in_map[sce->band_type[win*16+swb]] && sce->band_type[win*16+swb] > aac_cb_out_map[cb]) {

                    path[swb+1][cb].prev_idx = -1;

                    path[swb+1][cb].cost     = INFINITY;

                    path[swb+1][cb].run      = path[swb][cb].run + 1;

                    continue;

                }

                for (w = 0; w < group_len; w++) {

                    FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(win+w)*16+swb];

                    rd += quantize_band_cost(s, sce->coeffs + start + w*128,

                                             s->scoefs + start + w*128, size,

                                             sce->sf_idx[(win+w)*16+swb], aac_cb_out_map[cb],

                                             lambda / band->threshold, INFINITY, NULL, 0);

                }

                cost_stay_here = path[swb][cb].cost + rd;

                cost_get_here  = minrd              + rd + run_bits + 4;

                if (   run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run]

                    != run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run+1])

                    cost_stay_here += run_bits;

                if (cost_get_here < cost_stay_here) {

                    path[swb+1][cb].prev_idx = mincb;

                    path[swb+1][cb].cost     = cost_get_here;

                    path[swb+1][cb].run      = 1;

                } else {

                    path[swb+1][cb].prev_idx = cb;

                    path[swb+1][cb].cost     = cost_stay_here;

                    path[swb+1][cb].run      = path[swb][cb].run + 1;

                }

                if (path[swb+1][cb].cost < next_minrd) {

                    next_minrd = path[swb+1][cb].cost;

                    next_mincb = cb;

                }

            }

        }

        start += sce->ics.swb_sizes[swb];

    }

    //convert resulting path from backward-linked list

    stack_len = 0;

    idx       = 0;

    for (cb = 1; cb < CB_TOT_ALL; cb++)

        if (path[max_sfb][cb].cost < path[max_sfb][idx].cost)

            idx = cb;

    ppos = max_sfb;

    while (ppos > 0) {

        av_assert1(idx >= 0);

        cb = idx;

        stackrun[stack_len] = path[ppos][cb].run;

        stackcb [stack_len] = cb;

        idx = path[ppos-path[ppos][cb].run+1][cb].prev_idx;

        ppos -= path[ppos][cb].run;

        stack_len++;

    }

    //perform actual band info encoding

    start = 0;

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

        cb = aac_cb_out_map[stackcb[i]];

        put_bits(&s->pb, 4, cb);

        count = stackrun[i];

        memset(sce->zeroes + win*16 + start, !cb, count);

        //XXX: memset when band_type is also uint8_t

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

            sce->band_type[win*16 + start] = cb;

            start++;

        }

        while (count >= run_esc) {

            put_bits(&s->pb, run_bits, run_esc);

            count -= run_esc;

        }

        put_bits(&s->pb, run_bits, count);

    }

}


callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time)

{

    AVFormatContext *s = priv_data;

    struct dshow_ctx *ctx = s->priv_data;

    AVPacketList **ppktl, *pktl_next;

//    dump_videohdr(s, vdhdr);

    WaitForSingleObject(ctx->mutex, INFINITE);

    if(shall_we_drop(s, index))

        goto fail;

    pktl_next = av_mallocz(sizeof(AVPacketList));

    if(!pktl_next)

        goto fail;

    if(av_new_packet(&pktl_next->pkt, buf_size) < 0) {

        av_free(pktl_next);

        goto fail;

    }

    pktl_next->pkt.stream_index = index;

    pktl_next->pkt.pts = time;

    memcpy(pktl_next->pkt.data, buf, buf_size);

    for(ppktl = &ctx->pktl ; *ppktl ; ppktl = &(*ppktl)->next);

    *ppktl = pktl_next;

    ctx->curbufsize[index] += buf_size;

    SetEvent(ctx->event[1]);

    ReleaseMutex(ctx->mutex);

    return;

fail:

    ReleaseMutex(ctx->mutex);

    return;

}


void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value)

{

    size_t sz = strlen(value) + 1;

    return fw_cfg_add_bytes(s, key, (uint8_t *)g_memdup(value, sz), sz);

}


static void ide_flush_cache(IDEState *s)

{

    if (s->blk == NULL) {

        ide_flush_cb(s, 0);

        return;

    }

    s->status |= BUSY_STAT;

    ide_set_retry(s);

    block_acct_start(blk_get_stats(s->blk), &s->acct, 0, BLOCK_ACCT_FLUSH);

    s->pio_aiocb = blk_aio_flush(s->blk, ide_flush_cb, s);

}