static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,

                                                 const siginfo_t *info)

{

    int sig = host_to_target_signal(info->si_signo);

    tinfo->si_signo = sig;

    tinfo->si_errno = 0;

    tinfo->si_code = info->si_code;

    if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV

            || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) {

        /* Should never come here, but who knows. The information for

           the target is irrelevant.  */

        tinfo->_sifields._sigfault._addr = 0;

    } else if (sig == TARGET_SIGIO) {

        tinfo->_sifields._sigpoll._band = info->si_band;

        tinfo->_sifields._sigpoll._fd = info->si_fd;

    } else if (sig == TARGET_SIGCHLD) {

        tinfo->_sifields._sigchld._pid = info->si_pid;

        tinfo->_sifields._sigchld._uid = info->si_uid;

        tinfo->_sifields._sigchld._status

                = host_to_target_waitstatus(info->si_status);

        tinfo->_sifields._sigchld._utime = info->si_utime;

        tinfo->_sifields._sigchld._stime = info->si_stime;

    } else if (sig >= TARGET_SIGRTMIN) {

        tinfo->_sifields._rt._pid = info->si_pid;

        tinfo->_sifields._rt._uid = info->si_uid;

        /* XXX: potential problem if 64 bit */

        tinfo->_sifields._rt._sigval.sival_ptr

                = (abi_ulong)(unsigned long)info->si_value.sival_ptr;

    }

}


static int init_image(TiffContext *s, AVFrame *frame)
{
    int ret;
    switch (s->planar * 1000 + s->bpp * 10 + s->bppcount) {
    case 11:
        s->avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
        break;
    case 81:
        s->avctx->pix_fmt = s->palette_is_set ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
        break;
    case 243:
        s->avctx->pix_fmt = AV_PIX_FMT_RGB24;
        break;
    case 161:
        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GRAY16LE : AV_PIX_FMT_GRAY16BE;
        break;
    case 162:
        s->avctx->pix_fmt = AV_PIX_FMT_YA8;
        break;
    case 322:
        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_YA16LE : AV_PIX_FMT_YA16BE;
        break;
    case 324:
        s->avctx->pix_fmt = AV_PIX_FMT_RGBA;
        break;
    case 483:
        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGB48LE : AV_PIX_FMT_RGB48BE;
        break;
    case 644:
        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGBA64LE : AV_PIX_FMT_RGBA64BE;
        break;
    case 1243:
        s->avctx->pix_fmt = AV_PIX_FMT_GBRP;
        break;
    case 1324:
        s->avctx->pix_fmt = AV_PIX_FMT_GBRAP;
        break;
    case 1483:
        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GBRP16LE : AV_PIX_FMT_GBRP16BE;
        break;
    case 1644:
        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GBRAP16LE : AV_PIX_FMT_GBRAP16BE;
        break;
    default:
               "This format is not supported (bpp=%d, bppcount=%d)\n",
    if (s->width != s->avctx->width || s->height != s->avctx->height) {
        ret = ff_set_dimensions(s->avctx, s->width, s->height);
        if (ret < 0)
            return ret;
    if ((ret = ff_get_buffer(s->avctx, frame, 0)) < 0) {
        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return ret;
    if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {
        memcpy(frame->data[1], s->palette, sizeof(s->palette));
    return 0;


static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, int *tp_index,

                                  Jpeg2000CodingStyle *codsty,

                                  Jpeg2000ResLevel *rlevel, int precno,

                                  int layno, uint8_t *expn, int numgbits)

{

    int bandno, cblkno, ret, nb_code_blocks;

    int cwsno;

    if (bytestream2_get_bytes_left(&s->g) == 0 && s->bit_index == 8) {

        if (*tp_index < FF_ARRAY_ELEMS(tile->tile_part) - 1) {

            s->g = tile->tile_part[++(*tp_index)].tpg;

        }

    }

    if (bytestream2_peek_be32(&s->g) == 0xFF910004)

        bytestream2_skip(&s->g, 6);

    if (!(ret = get_bits(s, 1))) {

        jpeg2000_flush(s);

        return 0;

    } else if (ret < 0)

        return ret;

    for (bandno = 0; bandno < rlevel->nbands; bandno++) {

        Jpeg2000Band *band = rlevel->band + bandno;

        Jpeg2000Prec *prec = band->prec + precno;

        if (band->coord[0][0] == band->coord[0][1] ||

            band->coord[1][0] == band->coord[1][1])

            continue;

        nb_code_blocks =  prec->nb_codeblocks_height *

                          prec->nb_codeblocks_width;

        for (cblkno = 0; cblkno < nb_code_blocks; cblkno++) {

            Jpeg2000Cblk *cblk = prec->cblk + cblkno;

            int incl, newpasses, llen;

            if (cblk->npasses)

                incl = get_bits(s, 1);

            else

                incl = tag_tree_decode(s, prec->cblkincl + cblkno, layno + 1) == layno;

            if (!incl)

                continue;

            else if (incl < 0)

                return incl;

            if (!cblk->npasses) {

                int v = expn[bandno] + numgbits - 1 -

                        tag_tree_decode(s, prec->zerobits + cblkno, 100);

                if (v < 0) {

                    av_log(s->avctx, AV_LOG_ERROR,

                           "nonzerobits %d invalid\n", v);

                    return AVERROR_INVALIDDATA;

                }

                cblk->nonzerobits = v;

            }

            if ((newpasses = getnpasses(s)) < 0)

                return newpasses;

            av_assert2(newpasses > 0);

            if (cblk->npasses + newpasses >= JPEG2000_MAX_PASSES) {

                avpriv_request_sample(s->avctx, "Too many passes\n");

                return AVERROR_PATCHWELCOME;

            }

            if ((llen = getlblockinc(s)) < 0)

                return llen;

            if (cblk->lblock + llen + av_log2(newpasses) > 16) {

                avpriv_request_sample(s->avctx,

                                      "Block with length beyond 16 bits\n");

                return AVERROR_PATCHWELCOME;

            }

            cblk->lblock += llen;

            cblk->nb_lengthinc = 0;

            cblk->nb_terminationsinc = 0;

            do {

                int newpasses1 = 0;

                while (newpasses1 < newpasses) {

                    newpasses1 ++;

                    if (needs_termination(codsty->cblk_style, cblk->npasses + newpasses1 - 1)) {

                        cblk->nb_terminationsinc ++;

                        break;

                    }

                }

                if ((ret = get_bits(s, av_log2(newpasses1) + cblk->lblock)) < 0)

                    return ret;

                if (ret > sizeof(cblk->data)) {

                    avpriv_request_sample(s->avctx,

                                        "Block with lengthinc greater than %"SIZE_SPECIFIER"",

                                        sizeof(cblk->data));

                    return AVERROR_PATCHWELCOME;

                }

                cblk->lengthinc[cblk->nb_lengthinc++] = ret;

                cblk->npasses  += newpasses1;

                newpasses -= newpasses1;

            } while(newpasses);

        }

    }

    jpeg2000_flush(s);

    if (codsty->csty & JPEG2000_CSTY_EPH) {

        if (bytestream2_peek_be16(&s->g) == JPEG2000_EPH)

            bytestream2_skip(&s->g, 2);

        else

            av_log(s->avctx, AV_LOG_ERROR, "EPH marker not found.\n");

    }

    for (bandno = 0; bandno < rlevel->nbands; bandno++) {

        Jpeg2000Band *band = rlevel->band + bandno;

        Jpeg2000Prec *prec = band->prec + precno;

        nb_code_blocks = prec->nb_codeblocks_height * prec->nb_codeblocks_width;

        for (cblkno = 0; cblkno < nb_code_blocks; cblkno++) {

            Jpeg2000Cblk *cblk = prec->cblk + cblkno;

            for (cwsno = 0; cwsno < cblk->nb_lengthinc; cwsno ++) {

                if (   bytestream2_get_bytes_left(&s->g) < cblk->lengthinc[cwsno]

                    || sizeof(cblk->data) < cblk->length + cblk->lengthinc[cwsno] + 4

                ) {

                    av_log(s->avctx, AV_LOG_ERROR,

                        "Block length %"PRIu16" or lengthinc %d is too large, left %d\n",

                        cblk->length, cblk->lengthinc[cwsno], bytestream2_get_bytes_left(&s->g));

                    return AVERROR_INVALIDDATA;

                }

                bytestream2_get_bufferu(&s->g, cblk->data + cblk->length, cblk->lengthinc[cwsno]);

                cblk->length   += cblk->lengthinc[cwsno];

                cblk->lengthinc[cwsno] = 0;

                if (cblk->nb_terminationsinc) {

                    cblk->nb_terminationsinc--;

                    cblk->nb_terminations++;

                    cblk->data[cblk->length++] = 0xFF;

                    cblk->data[cblk->length++] = 0xFF;

                    cblk->data_start[cblk->nb_terminations] = cblk->length;

                }

            }

        }

    }

    return 0;

}


rdt_parse_sdp_line (AVFormatContext *s, int st_index,

                    PayloadContext *rdt, const char *line)

{

    AVStream *stream = s->streams[st_index];

    const char *p = line;

    if (av_strstart(p, "OpaqueData:buffer;", &p)) {

        rdt->mlti_data = rdt_parse_b64buf(&rdt->mlti_data_size, p);

    } else if (av_strstart(p, "StartTime:integer;", &p))

        stream->first_dts = atoi(p);

    else if (av_strstart(p, "ASMRuleBook:string;", &p)) {

        int n, first = -1;

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

            if (s->streams[n]->id == stream->id) {

                int count = s->streams[n]->index + 1;

                if (first == -1) first = n;

                if (rdt->nb_rmst < count) {

                    RMStream **rmst= av_realloc(rdt->rmst, count*sizeof(*rmst));

                    if (!rmst)

                        return AVERROR(ENOMEM);

                    memset(rmst + rdt->nb_rmst, 0,

                           (count - rdt->nb_rmst) * sizeof(*rmst));

                    rdt->rmst    = rmst;

                    rdt->nb_rmst = count;

                }

                rdt->rmst[s->streams[n]->index] = ff_rm_alloc_rmstream();

                rdt_load_mdpr(rdt, s->streams[n], (n - first) * 2);

                if (s->streams[n]->codec->codec_id == CODEC_ID_AAC)

                    s->streams[n]->codec->frame_size = 1; // FIXME

           }

    }

    return 0;

}


static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel,

                                     const float *coefs, const FFPsyWindowInfo *wi)

{

    AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;

    AacPsyChannel *pch  = &pctx->ch[channel];

    int i, w, g;

    float desired_bits, desired_pe, delta_pe, reduction= NAN, spread_en[128] = {0};

    float a = 0.0f, active_lines = 0.0f, norm_fac = 0.0f;

    float pe = pctx->chan_bitrate > 32000 ? 0.0f : FFMAX(50.0f, 100.0f - pctx->chan_bitrate * 100.0f / 32000.0f);

    const int      num_bands   = ctx->num_bands[wi->num_windows == 8];

    const uint8_t *band_sizes  = ctx->bands[wi->num_windows == 8];

    AacPsyCoeffs  *coeffs      = pctx->psy_coef[wi->num_windows == 8];

    const float avoid_hole_thr = wi->num_windows == 8 ? PSY_3GPP_AH_THR_SHORT : PSY_3GPP_AH_THR_LONG;

    //calculate energies, initial thresholds and related values - 5.4.2 "Threshold Calculation"

    calc_thr_3gpp(wi, num_bands, pch, band_sizes, coefs);

    //modify thresholds and energies - spread, threshold in quiet, pre-echo control

    for (w = 0; w < wi->num_windows*16; w += 16) {

        AacPsyBand *bands = &pch->band[w];

        /* 5.4.2.3 "Spreading" & 5.4.3 "Spread Energy Calculation" */

        spread_en[0] = bands[0].energy;

        for (g = 1; g < num_bands; g++) {

            bands[g].thr   = FFMAX(bands[g].thr,    bands[g-1].thr * coeffs[g].spread_hi[0]);

            spread_en[w+g] = FFMAX(bands[g].energy, spread_en[w+g-1] * coeffs[g].spread_hi[1]);

        }

        for (g = num_bands - 2; g >= 0; g--) {

            bands[g].thr   = FFMAX(bands[g].thr,   bands[g+1].thr * coeffs[g].spread_low[0]);

            spread_en[w+g] = FFMAX(spread_en[w+g], spread_en[w+g+1] * coeffs[g].spread_low[1]);

        }

        //5.4.2.4 "Threshold in quiet"

        for (g = 0; g < num_bands; g++) {

            AacPsyBand *band = &bands[g];

            band->thr_quiet = band->thr = FFMAX(band->thr, coeffs[g].ath);

            //5.4.2.5 "Pre-echo control"

            if (!(wi->window_type[0] == LONG_STOP_SEQUENCE || (wi->window_type[1] == LONG_START_SEQUENCE && !w)))

                band->thr = FFMAX(PSY_3GPP_RPEMIN*band->thr, FFMIN(band->thr,

                                  PSY_3GPP_RPELEV*pch->prev_band[w+g].thr_quiet));

            /* 5.6.1.3.1 "Preparatory steps of the perceptual entropy calculation" */

            pe += calc_pe_3gpp(band);

            a  += band->pe_const;

            active_lines += band->active_lines;

            /* 5.6.1.3.3 "Selection of the bands for avoidance of holes" */

            if (spread_en[w+g] * avoid_hole_thr > band->energy || coeffs[g].min_snr > 1.0f)

                band->avoid_holes = PSY_3GPP_AH_NONE;

            else

                band->avoid_holes = PSY_3GPP_AH_INACTIVE;

        }

    }

    /* 5.6.1.3.2 "Calculation of the desired perceptual entropy" */

    ctx->ch[channel].entropy = pe;

    desired_bits = calc_bit_demand(pctx, pe, ctx->bitres.bits, ctx->bitres.size, wi->num_windows == 8);

    desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits);

    /* NOTE: PE correction is kept simple. During initial testing it had very

     *       little effect on the final bitrate. Probably a good idea to come

     *       back and do more testing later.

     */

    if (ctx->bitres.bits > 0)

        desired_pe *= av_clipf(pctx->pe.previous / PSY_3GPP_BITS_TO_PE(ctx->bitres.bits),

                               0.85f, 1.15f);

    pctx->pe.previous = PSY_3GPP_BITS_TO_PE(desired_bits);

    if (desired_pe < pe) {

        /* 5.6.1.3.4 "First Estimation of the reduction value" */

        for (w = 0; w < wi->num_windows*16; w += 16) {

            reduction = calc_reduction_3gpp(a, desired_pe, pe, active_lines);

            pe = 0.0f;

            a  = 0.0f;

            active_lines = 0.0f;

            for (g = 0; g < num_bands; g++) {

                AacPsyBand *band = &pch->band[w+g];

                band->thr = calc_reduced_thr_3gpp(band, coeffs[g].min_snr, reduction);

                /* recalculate PE */

                pe += calc_pe_3gpp(band);

                a  += band->pe_const;

                active_lines += band->active_lines;

            }

        }

        /* 5.6.1.3.5 "Second Estimation of the reduction value" */

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

            float pe_no_ah = 0.0f, desired_pe_no_ah;

            active_lines = a = 0.0f;

            for (w = 0; w < wi->num_windows*16; w += 16) {

                for (g = 0; g < num_bands; g++) {

                    AacPsyBand *band = &pch->band[w+g];

                    if (band->avoid_holes != PSY_3GPP_AH_ACTIVE) {

                        pe_no_ah += band->pe;

                        a        += band->pe_const;

                        active_lines += band->active_lines;

                    }

                }

            }

            desired_pe_no_ah = FFMAX(desired_pe - (pe - pe_no_ah), 0.0f);

            if (active_lines > 0.0f)

                reduction += calc_reduction_3gpp(a, desired_pe_no_ah, pe_no_ah, active_lines);

            pe = 0.0f;

            for (w = 0; w < wi->num_windows*16; w += 16) {

                for (g = 0; g < num_bands; g++) {

                    AacPsyBand *band = &pch->band[w+g];

                    if (active_lines > 0.0f)

                        band->thr = calc_reduced_thr_3gpp(band, coeffs[g].min_snr, reduction);

                    pe += calc_pe_3gpp(band);

                    band->norm_fac = band->active_lines / band->thr;

                    norm_fac += band->norm_fac;

                }

            }

            delta_pe = desired_pe - pe;

            if (fabs(delta_pe) > 0.05f * desired_pe)

                break;

        }

        if (pe < 1.15f * desired_pe) {

            /* 6.6.1.3.6 "Final threshold modification by linearization" */

            norm_fac = 1.0f / norm_fac;

            for (w = 0; w < wi->num_windows*16; w += 16) {

                for (g = 0; g < num_bands; g++) {

                    AacPsyBand *band = &pch->band[w+g];

                    if (band->active_lines > 0.5f) {

                        float delta_sfb_pe = band->norm_fac * norm_fac * delta_pe;

                        float thr = band->thr;

                        thr *= exp2f(delta_sfb_pe / band->active_lines);

                        if (thr > coeffs[g].min_snr * band->energy && band->avoid_holes == PSY_3GPP_AH_INACTIVE)

                            thr = FFMAX(band->thr, coeffs[g].min_snr * band->energy);

                        band->thr = thr;

                    }

                }

            }

        } else {

            /* 5.6.1.3.7 "Further perceptual entropy reduction" */

            g = num_bands;

            while (pe > desired_pe && g--) {

                for (w = 0; w < wi->num_windows*16; w+= 16) {

                    AacPsyBand *band = &pch->band[w+g];

                    if (band->avoid_holes != PSY_3GPP_AH_NONE && coeffs[g].min_snr < PSY_SNR_1DB) {

                        coeffs[g].min_snr = PSY_SNR_1DB;

                        band->thr = band->energy * PSY_SNR_1DB;

                        pe += band->active_lines * 1.5f - band->pe;

                    }

                }

            }

            /* TODO: allow more holes (unused without mid/side) */

        }

    }

    for (w = 0; w < wi->num_windows*16; w += 16) {

        for (g = 0; g < num_bands; g++) {

            AacPsyBand *band     = &pch->band[w+g];

            FFPsyBand  *psy_band = &ctx->ch[channel].psy_bands[w+g];

            psy_band->threshold = band->thr;

            psy_band->energy    = band->energy;

        }

    }

    memcpy(pch->prev_band, pch->band, sizeof(pch->band));

}


static int avi_write_ix(AVFormatContext *s)

{

    AVIOContext *pb = s->pb;

    AVIContext *avi = s->priv_data;

    char tag[5];

    char ix_tag[] = "ix00";

    int i, j;

    assert(pb->seekable);

    if (avi->riff_id > AVI_MASTER_INDEX_SIZE)

        return -1;

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

        AVIStream *avist = s->streams[i]->priv_data;

        int64_t ix, pos;

        avi_stream2fourcc(tag, i, s->streams[i]->codecpar->codec_type);

        ix_tag[3] = '0' + i;

        /* Writing AVI OpenDML leaf index chunk */

        ix = avio_tell(pb);

        ffio_wfourcc(pb, ix_tag);      /* ix?? */

        avio_wl32(pb, avist->indexes.entry * 8 + 24);

        /* chunk size */

        avio_wl16(pb, 2);           /* wLongsPerEntry */

        avio_w8(pb, 0);             /* bIndexSubType (0 == frame index) */

        avio_w8(pb, 1);             /* bIndexType (1 == AVI_INDEX_OF_CHUNKS) */

        avio_wl32(pb, avist->indexes.entry);

        /* nEntriesInUse */

        ffio_wfourcc(pb, tag);         /* dwChunkId */

        avio_wl64(pb, avi->movi_list); /* qwBaseOffset */

        avio_wl32(pb, 0);              /* dwReserved_3 (must be 0) */

        for (j = 0; j < avist->indexes.entry; j++) {

            AVIIentry *ie = avi_get_ientry(&avist->indexes, j);

            avio_wl32(pb, ie->pos + 8);

            avio_wl32(pb, ((uint32_t) ie->len & ~0x80000000) |

                          (ie->flags & 0x10 ? 0 : 0x80000000));

        }

        avio_flush(pb);

        pos = avio_tell(pb);

        /* Updating one entry in the AVI OpenDML master index */

        avio_seek(pb, avist->indexes.indx_start - 8, SEEK_SET);

        ffio_wfourcc(pb, "indx");             /* enabling this entry */

        avio_skip(pb, 8);

        avio_wl32(pb, avi->riff_id);          /* nEntriesInUse */

        avio_skip(pb, 16 * avi->riff_id);

        avio_wl64(pb, ix);                    /* qwOffset */

        avio_wl32(pb, pos - ix);              /* dwSize */

        avio_wl32(pb, avist->indexes.entry);  /* dwDuration */

        avio_seek(pb, pos, SEEK_SET);

    }

    return 0;

}


int ff_dxva2_decode_init(AVCodecContext *avctx)

{

    FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);

    AVHWFramesContext *frames_ctx = NULL;

    int ret = 0;

    // Old API.

    if (avctx->hwaccel_context)

        return 0;

    // (avctx->pix_fmt is not updated yet at this point)

    sctx->pix_fmt = avctx->hwaccel->pix_fmt;

    if (avctx->codec_id == AV_CODEC_ID_H264 &&

        (avctx->profile & ~FF_PROFILE_H264_CONSTRAINED) > FF_PROFILE_H264_HIGH) {

        av_log(avctx, AV_LOG_VERBOSE, "Unsupported H.264 profile for DXVA HWAccel: %d\n",avctx->profile);

        return AVERROR(ENOTSUP);

    }

    if (avctx->codec_id == AV_CODEC_ID_HEVC &&

        avctx->profile != FF_PROFILE_HEVC_MAIN && avctx->profile != FF_PROFILE_HEVC_MAIN_10) {

        av_log(avctx, AV_LOG_VERBOSE, "Unsupported HEVC profile for DXVA HWAccel: %d\n", avctx->profile);

        return AVERROR(ENOTSUP);

    }

    if (!avctx->hw_frames_ctx && !avctx->hw_device_ctx) {

        av_log(avctx, AV_LOG_ERROR, "Either a hw_frames_ctx or a hw_device_ctx needs to be set for hardware decoding.\n");

        return AVERROR(EINVAL);

    }

    if (avctx->hw_frames_ctx) {

        frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;

    } else {

        avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx);

        if (!avctx->hw_frames_ctx)

            return AVERROR(ENOMEM);

        frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;

        dxva_adjust_hwframes(avctx, frames_ctx);

        ret = av_hwframe_ctx_init(avctx->hw_frames_ctx);

        if (ret < 0)

            goto fail;

    }

    sctx->device_ctx = frames_ctx->device_ctx;

    if (frames_ctx->format != sctx->pix_fmt ||

        !((sctx->pix_fmt == AV_PIX_FMT_D3D11 && CONFIG_D3D11VA) ||

          (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && CONFIG_DXVA2))) {

        av_log(avctx, AV_LOG_ERROR, "Invalid pixfmt for hwaccel!\n");

        ret = AVERROR(EINVAL);

        goto fail;

    }

#if CONFIG_D3D11VA

    if (sctx->pix_fmt == AV_PIX_FMT_D3D11) {

        AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;

        AVD3D11VAContext *d3d11_ctx = &sctx->ctx.d3d11va;

        HRESULT hr;

        ff_dxva2_lock(avctx);

        ret = d3d11va_create_decoder(avctx);

        ff_dxva2_unlock(avctx);

        if (ret < 0)

            goto fail;

        d3d11_ctx->decoder       = sctx->d3d11_decoder;

        d3d11_ctx->video_context = device_hwctx->video_context;

        d3d11_ctx->cfg           = &sctx->d3d11_config;

        d3d11_ctx->surface_count = sctx->nb_d3d11_views;

        d3d11_ctx->surface       = sctx->d3d11_views;

        d3d11_ctx->workaround    = sctx->workaround;

        d3d11_ctx->context_mutex = INVALID_HANDLE_VALUE;

    }

#endif

#if CONFIG_DXVA2

    if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {

        AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx;

        struct dxva_context *dxva_ctx = &sctx->ctx.dxva2;

        ff_dxva2_lock(avctx);

        ret = dxva2_create_decoder(avctx);

        ff_dxva2_unlock(avctx);

        if (ret < 0)

            goto fail;

        dxva_ctx->decoder       = sctx->dxva2_decoder;

        dxva_ctx->cfg           = &sctx->dxva2_config;

        dxva_ctx->surface       = frames_hwctx->surfaces;

        dxva_ctx->surface_count = frames_hwctx->nb_surfaces;

        dxva_ctx->workaround    = sctx->workaround;

    }

#endif

    return 0;

fail:

    ff_dxva2_decode_uninit(avctx);

    return ret;

}


static av_cold int twolame_encode_init(AVCodecContext *avctx)

{

    TWOLAMEContext *s = avctx->priv_data;

    int ret;

    avctx->frame_size = TWOLAME_SAMPLES_PER_FRAME;

    avctx->delay      = 512 - 32 + 1;

    s->glopts = twolame_init();

    if (!s->glopts)

        return AVERROR(ENOMEM);

    twolame_set_verbosity(s->glopts, s->verbosity);

    twolame_set_mode(s->glopts, s->mode);

    twolame_set_psymodel(s->glopts, s->psymodel);

    twolame_set_energy_levels(s->glopts, s->energy);

    twolame_set_error_protection(s->glopts, s->error_protection);

    twolame_set_copyright(s->glopts, s->copyright);

    twolame_set_original(s->glopts, s->original);

    twolame_set_num_channels(s->glopts, avctx->channels);

    twolame_set_in_samplerate(s->glopts, avctx->sample_rate);

    twolame_set_out_samplerate(s->glopts, avctx->sample_rate);

    if (avctx->flags & CODEC_FLAG_QSCALE || !avctx->bit_rate) {

        twolame_set_VBR(s->glopts, TRUE);

        twolame_set_VBR_level(s->glopts,

                              avctx->global_quality / (float) FF_QP2LAMBDA);

        av_log(avctx, AV_LOG_WARNING,

               "VBR in MP2 is a hack, use another codec that supports it.\n");

    } else {

        twolame_set_bitrate(s->glopts, avctx->bit_rate / 1000);

    }

    ret = twolame_init_params(s->glopts);

    if (ret) {

        twolame_encode_close(avctx);

        return AVERROR_UNKNOWN;

    }

    return 0;

}


static int decode_frame(AVCodecContext *avctx,
                        void *data, int *got_frame,
                        AVPacket *avpkt)
{
    SheerVideoContext *s = avctx->priv_data;
    ThreadFrame frame = { .f = data };
    AVFrame *p = data;
    GetBitContext gb;
    unsigned format;
    int ret;
    if (avpkt->size <= 20)
    if (AV_RL32(avpkt->data) != MKTAG('S','h','i','r') &&
        AV_RL32(avpkt->data) != MKTAG('Z','w','a','k'))
    s->alt = 0;
    format = AV_RL32(avpkt->data + 16);
    av_log(avctx, AV_LOG_DEBUG, "format: %s\n", av_fourcc2str(format));
    switch (format) {
    case MKTAG(' ', 'R', 'G', 'B'):
        avctx->pix_fmt = AV_PIX_FMT_RGB0;
        s->decode_frame = decode_rgb;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_r_rgb, 256);
            ret |= build_vlc(&s->vlc[1], l_g_rgb, 256);
        break;
    case MKTAG(' ', 'r', 'G', 'B'):
        avctx->pix_fmt = AV_PIX_FMT_RGB0;
        s->decode_frame = decode_rgbi;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_r_rgbi, 256);
            ret |= build_vlc(&s->vlc[1], l_g_rgbi, 256);
        break;
    case MKTAG('A', 'R', 'G', 'X'):
        avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
        s->decode_frame = decode_argx;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_r_rgbx, 1024);
            ret |= build_vlc(&s->vlc[1], l_g_rgbx, 1024);
        break;
    case MKTAG('A', 'r', 'G', 'X'):
        avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
        s->decode_frame = decode_argxi;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_r_rgbxi, 1024);
            ret |= build_vlc(&s->vlc[1], l_g_rgbxi, 1024);
        break;
    case MKTAG('R', 'G', 'B', 'X'):
        avctx->pix_fmt = AV_PIX_FMT_GBRP10;
        s->decode_frame = decode_rgbx;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_r_rgbx, 1024);
            ret |= build_vlc(&s->vlc[1], l_g_rgbx, 1024);
        break;
    case MKTAG('r', 'G', 'B', 'X'):
        avctx->pix_fmt = AV_PIX_FMT_GBRP10;
        s->decode_frame = decode_rgbxi;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_r_rgbxi, 1024);
            ret |= build_vlc(&s->vlc[1], l_g_rgbxi, 1024);
        break;
    case MKTAG('A', 'R', 'G', 'B'):
        avctx->pix_fmt = AV_PIX_FMT_ARGB;
        s->decode_frame = decode_argb;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_r_rgb, 256);
            ret |= build_vlc(&s->vlc[1], l_g_rgb, 256);
        break;
    case MKTAG('A', 'r', 'G', 'B'):
        avctx->pix_fmt = AV_PIX_FMT_ARGB;
        s->decode_frame = decode_argbi;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_r_rgbi, 256);
            ret |= build_vlc(&s->vlc[1], l_g_rgbi, 256);
        break;
    case MKTAG('A', 'Y', 'B', 'R'):
        s->alt = 1;
    case MKTAG('A', 'Y', 'b', 'R'):
        avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
        s->decode_frame = decode_aybr;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_ybr, 256);
            ret |= build_vlc(&s->vlc[1], l_u_ybr, 256);
        break;
    case MKTAG('A', 'y', 'B', 'R'):
        s->alt = 1;
    case MKTAG('A', 'y', 'b', 'R'):
        avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
        s->decode_frame = decode_aybri;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_ybri, 256);
            ret |= build_vlc(&s->vlc[1], l_u_ybri, 256);
        break;
    case MKTAG(' ', 'Y', 'B', 'R'):
        s->alt = 1;
    case MKTAG(' ', 'Y', 'b', 'R'):
        avctx->pix_fmt = AV_PIX_FMT_YUV444P;
        s->decode_frame = decode_ybr;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_ybr, 256);
            ret |= build_vlc(&s->vlc[1], l_u_ybr, 256);
        break;
    case MKTAG(' ', 'y', 'B', 'R'):
        s->alt = 1;
    case MKTAG(' ', 'y', 'b', 'R'):
        avctx->pix_fmt = AV_PIX_FMT_YUV444P;
        s->decode_frame = decode_ybri;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_ybri, 256);
            ret |= build_vlc(&s->vlc[1], l_u_ybri, 256);
        break;
    case MKTAG('Y', 'B', 'R', 0x0a):
        avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
        s->decode_frame = decode_ybr10;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_ybr10, 1024);
            ret |= build_vlc(&s->vlc[1], l_u_ybr10, 1024);
        break;
    case MKTAG('y', 'B', 'R', 0x0a):
        avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
        s->decode_frame = decode_ybr10i;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_ybr10i, 1024);
            ret |= build_vlc(&s->vlc[1], l_u_ybr10i, 1024);
        break;
    case MKTAG('C', 'A', '4', 'p'):
        avctx->pix_fmt = AV_PIX_FMT_YUVA444P10;
        s->decode_frame = decode_ca4p;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_ybr10, 1024);
            ret |= build_vlc(&s->vlc[1], l_u_ybr10, 1024);
        break;
    case MKTAG('C', 'A', '4', 'i'):
        avctx->pix_fmt = AV_PIX_FMT_YUVA444P10;
        s->decode_frame = decode_ca4i;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_ybr10i, 1024);
            ret |= build_vlc(&s->vlc[1], l_u_ybr10i, 1024);
        break;
    case MKTAG('B', 'Y', 'R', 'Y'):
        avctx->pix_fmt = AV_PIX_FMT_YUV422P;
        s->decode_frame = decode_byry;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_byry, 256);
            ret |= build_vlc(&s->vlc[1], l_u_byry, 256);
        break;
    case MKTAG('B', 'Y', 'R', 'y'):
        avctx->pix_fmt = AV_PIX_FMT_YUV422P;
        s->decode_frame = decode_byryi;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_byryi, 256);
            ret |= build_vlc(&s->vlc[1], l_u_byryi, 256);
        break;
    case MKTAG('Y', 'b', 'Y', 'r'):
        avctx->pix_fmt = AV_PIX_FMT_YUV422P;
        s->decode_frame = decode_ybyr;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_ybyr, 256);
            ret |= build_vlc(&s->vlc[1], l_u_ybyr, 256);
        break;
    case MKTAG('C', '8', '2', 'p'):
        avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
        s->decode_frame = decode_c82p;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_byry, 256);
            ret |= build_vlc(&s->vlc[1], l_u_byry, 256);
        break;
    case MKTAG('C', '8', '2', 'i'):
        avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
        s->decode_frame = decode_c82i;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_byryi, 256);
            ret |= build_vlc(&s->vlc[1], l_u_byryi, 256);
        break;
    case MKTAG(0xa2, 'Y', 'R', 'Y'):
        avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
        s->decode_frame = decode_yry10;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_yry10, 1024);
            ret |= build_vlc(&s->vlc[1], l_u_yry10, 1024);
        break;
    case MKTAG(0xa2, 'Y', 'R', 'y'):
        avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
        s->decode_frame = decode_yry10i;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_yry10i, 1024);
            ret |= build_vlc(&s->vlc[1], l_u_yry10i, 1024);
        break;
    case MKTAG('C', 'A', '2', 'p'):
        avctx->pix_fmt = AV_PIX_FMT_YUVA422P10;
        s->decode_frame = decode_ca2p;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_yry10, 1024);
            ret |= build_vlc(&s->vlc[1], l_u_yry10, 1024);
        break;
    case MKTAG('C', 'A', '2', 'i'):
        avctx->pix_fmt = AV_PIX_FMT_YUVA422P10;
        s->decode_frame = decode_ca2i;
        if (s->format != format) {
            ret  = build_vlc(&s->vlc[0], l_y_yry10i, 1024);
            ret |= build_vlc(&s->vlc[1], l_u_yry10i, 1024);
        break;
    default:
        avpriv_request_sample(avctx, "unsupported format: 0x%X", format);
        return AVERROR_PATCHWELCOME;
    if (s->format != format) {
        if (ret < 0)
            return ret;
        s->format = format;
    p->pict_type = AV_PICTURE_TYPE_I;
    p->key_frame = 1;
    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
        return ret;
    if ((ret = init_get_bits8(&gb, avpkt->data + 20, avpkt->size - 20)) < 0)
        return ret;
    s->decode_frame(avctx, p, &gb);
    *got_frame = 1;
    return avpkt->size;


static int count_contiguous_clusters(uint64_t nb_clusters, int cluster_size,

        uint64_t *l2_table, uint64_t mask)

{

    int i;

    uint64_t offset = be64_to_cpu(l2_table[0]) & ~mask;

    if (!offset)

        return 0;

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

        if (offset + i * cluster_size != (be64_to_cpu(l2_table[i]) & ~mask))

            break;

	return i;

}


static int add_metadata_from_side_data(AVCodecContext *avctx, AVFrame *frame)

{

    int size, ret = 0;

    const uint8_t *side_metadata;

    const uint8_t *end;

    side_metadata = av_packet_get_side_data(avctx->pkt,

                                            AV_PKT_DATA_STRINGS_METADATA, &size);

    if (!side_metadata)

        goto end;

    end = side_metadata + size;

    while (side_metadata < end) {

        const uint8_t *key = side_metadata;

        const uint8_t *val = side_metadata + strlen(key) + 1;

        int ret = av_dict_set(avpriv_frame_get_metadatap(frame), key, val, 0);

        if (ret < 0)

            break;

        side_metadata = val + strlen(val) + 1;

    }

end:

    return ret;

}


static void parse_type_str(Visitor *v, const char *name, char **obj,

                           Error **errp)

{

    StringInputVisitor *siv = to_siv(v);

    if (siv->string) {

        *obj = g_strdup(siv->string);

    } else {

        *obj = NULL;

        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",

                   "string");

    }

}


static void register_subpage(MemoryRegionSection *section)

{

    subpage_t *subpage;

    target_phys_addr_t base = section->offset_within_address_space

        & TARGET_PAGE_MASK;

    MemoryRegionSection *existing = phys_page_find(base >> TARGET_PAGE_BITS);

    MemoryRegionSection subsection = {

        .offset_within_address_space = base,

        .size = TARGET_PAGE_SIZE,

    };

    target_phys_addr_t start, end;

    assert(existing->mr->subpage || existing->mr == &io_mem_unassigned);

    if (!(existing->mr->subpage)) {

        subpage = subpage_init(base);

        subsection.mr = &subpage->iomem;

        phys_page_set(base >> TARGET_PAGE_BITS, 1,

                      phys_section_add(&subsection));

    } else {

        subpage = container_of(existing->mr, subpage_t, iomem);

    }

    start = section->offset_within_address_space & ~TARGET_PAGE_MASK;

    end = start + section->size;

    subpage_register(subpage, start, end, phys_section_add(section));

}


static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height)

{

    const uint8_t *frame_end   = frame + width * height;

    uint8_t *line_ptr;

    int count, i, v, lines, segments;

    int y = 0;

    lines = bytestream2_get_le16(gb);

    if (lines > height)

        return AVERROR_INVALIDDATA;

    while (lines--) {

        if (bytestream2_get_bytes_left(gb) < 2)

            return AVERROR_INVALIDDATA;

        segments = bytestream2_get_le16u(gb);

        while ((segments & 0xC000) == 0xC000) {

            unsigned skip_lines = -(int16_t)segments;

            unsigned delta = -((int16_t)segments * width);

            if (frame_end - frame <= delta || y + lines + skip_lines > height)

                return AVERROR_INVALIDDATA;

            frame    += delta;

            y        += skip_lines;

            segments = bytestream2_get_le16(gb);

        }

        if (frame_end <= frame)

            return AVERROR_INVALIDDATA;

        if (segments & 0x8000) {

            frame[width - 1] = segments & 0xFF;

            segments = bytestream2_get_le16(gb);

        }

        line_ptr = frame;

        if (frame_end - frame < width)

            return AVERROR_INVALIDDATA;

        frame += width;

        y++;

        while (segments--) {

            if (frame - line_ptr <= bytestream2_peek_byte(gb))

                return AVERROR_INVALIDDATA;

            line_ptr += bytestream2_get_byte(gb);

            count = (int8_t)bytestream2_get_byte(gb);

            if (count >= 0) {

                if (frame - line_ptr < count * 2)

                    return AVERROR_INVALIDDATA;

                if (bytestream2_get_buffer(gb, line_ptr, count * 2) != count * 2)

                    return AVERROR_INVALIDDATA;

                line_ptr += count * 2;

            } else {

                count = -count;

                if (frame - line_ptr < count * 2)

                    return AVERROR_INVALIDDATA;

                v = bytestream2_get_le16(gb);

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

                    bytestream_put_le16(&line_ptr, v);

            }

        }

    }

    return 0;

}


static void adb_mouse_event(void *opaque,

                            int dx1, int dy1, int dz1, int buttons_state)

{

    MouseState *s = opaque;

    s->dx += dx1;

    s->dy += dy1;

    s->dz += dz1;

    s->buttons_state = buttons_state;

}


void cache_insert(PageCache *cache, uint64_t addr, uint8_t *pdata)
{
    CacheItem *it = NULL;
    g_assert(cache);
    g_assert(cache->page_cache);
    /* actual update of entry */
    it = cache_get_by_addr(cache, addr);
    if (!it->it_data) {
        cache->num_items++;
    }
    it->it_data = pdata;
    it->it_age = ++cache->max_item_age;
    it->it_addr = addr;
}


void replay_bh_schedule_event(QEMUBH *bh)

{

    if (replay_mode != REPLAY_MODE_NONE) {

        uint64_t id = replay_get_current_step();

        replay_add_event(REPLAY_ASYNC_EVENT_BH, bh, NULL, id);

    } else {

        qemu_bh_schedule(bh);

    }

}


static FFPsyWindowInfo psy_lame_window(FFPsyContext *ctx,

                                       const int16_t *audio, const int16_t *la,

                                       int channel, int prev_type)

{

    AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;

    AacPsyChannel *pch  = &pctx->ch[channel];

    int grouping     = 0;

    int uselongblock = 1;

    int attacks[AAC_NUM_BLOCKS_SHORT + 1] = { 0 };

    int i;

    FFPsyWindowInfo wi;

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

    if (la) {

        float hpfsmpl[AAC_BLOCK_SIZE_LONG];

        float const *pf = hpfsmpl;

        float attack_intensity[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS];

        float energy_subshort[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS];

        float energy_short[AAC_NUM_BLOCKS_SHORT + 1] = { 0 };

        int chans = ctx->avctx->channels;

        const int16_t *firbuf = la + (AAC_BLOCK_SIZE_SHORT/4 - PSY_LAME_FIR_LEN) * chans;

        int j, att_sum = 0;

        /* LAME comment: apply high pass filter of fs/4 */

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

            float sum1, sum2;

            sum1 = firbuf[(i + ((PSY_LAME_FIR_LEN - 1) / 2)) * chans];

            sum2 = 0.0;

            for (j = 0; j < ((PSY_LAME_FIR_LEN - 1) / 2) - 1; j += 2) {

                sum1 += psy_fir_coeffs[j] * (firbuf[(i + j) * chans] + firbuf[(i + PSY_LAME_FIR_LEN - j) * chans]);

                sum2 += psy_fir_coeffs[j + 1] * (firbuf[(i + j + 1) * chans] + firbuf[(i + PSY_LAME_FIR_LEN - j - 1) * chans]);

            }

            hpfsmpl[i] = sum1 + sum2;

        }

        /* Calculate the energies of each sub-shortblock */

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

            energy_subshort[i] = pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 1) * PSY_LAME_NUM_SUBBLOCKS)];

            assert(pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 2) * PSY_LAME_NUM_SUBBLOCKS + 1)] > 0);

            attack_intensity[i] = energy_subshort[i] / pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 2) * PSY_LAME_NUM_SUBBLOCKS + 1)];

            energy_short[0] += energy_subshort[i];

        }

        for (i = 0; i < AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS; i++) {

            float const *const pfe = pf + AAC_BLOCK_SIZE_LONG / (AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS);

            float p = 1.0f;

            for (; pf < pfe; pf++)

                if (p < fabsf(*pf))

                    p = fabsf(*pf);

            pch->prev_energy_subshort[i] = energy_subshort[i + PSY_LAME_NUM_SUBBLOCKS] = p;

            energy_short[1 + i / PSY_LAME_NUM_SUBBLOCKS] += p;

            /* FIXME: The indexes below are [i + 3 - 2] in the LAME source.

             *          Obviously the 3 and 2 have some significance, or this would be just [i + 1]

             *          (which is what we use here). What the 3 stands for is ambigious, as it is both

             *          number of short blocks, and the number of sub-short blocks.

             *          It seems that LAME is comparing each sub-block to sub-block + 1 in the

             *          previous block.

             */

            if (p > energy_subshort[i + 1])

                p = p / energy_subshort[i + 1];

            else if (energy_subshort[i + 1] > p * 10.0f)

                p = energy_subshort[i + 1] / (p * 10.0f);

            else

                p = 0.0;

            attack_intensity[i + PSY_LAME_NUM_SUBBLOCKS] = p;

        }

        /* compare energy between sub-short blocks */

        for (i = 0; i < (AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS; i++)

            if (!attacks[i / PSY_LAME_NUM_SUBBLOCKS])

                if (attack_intensity[i] > pch->attack_threshold)

                    attacks[i / PSY_LAME_NUM_SUBBLOCKS] = (i % PSY_LAME_NUM_SUBBLOCKS) + 1;

        /* should have energy change between short blocks, in order to avoid periodic signals */

        /* Good samples to show the effect are Trumpet test songs */

        /* GB: tuned (1) to avoid too many short blocks for test sample TRUMPET */

        /* RH: tuned (2) to let enough short blocks through for test sample FSOL and SNAPS */

        for (i = 1; i < AAC_NUM_BLOCKS_SHORT + 1; i++) {

            float const u = energy_short[i - 1];

            float const v = energy_short[i];

            float const m = FFMAX(u, v);

            if (m < 40000) {                          /* (2) */

                if (u < 1.7f * v && v < 1.7f * u) {   /* (1) */

                    if (i == 1 && attacks[0] < attacks[i])

                        attacks[0] = 0;

                    attacks[i] = 0;

                }

            }

            att_sum += attacks[i];

        }

        if (attacks[0] <= pch->prev_attack)

            attacks[0] = 0;

        att_sum += attacks[0];

        /* 3 below indicates the previous attack happened in the last sub-block of the previous sequence */

        if (pch->prev_attack == 3 || att_sum) {

            uselongblock = 0;

            if (attacks[1] && attacks[0])

                attacks[1] = 0;

            if (attacks[2] && attacks[1])

                attacks[2] = 0;

            if (attacks[3] && attacks[2])

                attacks[3] = 0;

            if (attacks[4] && attacks[3])

                attacks[4] = 0;

            if (attacks[5] && attacks[4])

                attacks[5] = 0;

            if (attacks[6] && attacks[5])

                attacks[6] = 0;

            if (attacks[7] && attacks[6])

                attacks[7] = 0;

            if (attacks[8] && attacks[7])

                attacks[8] = 0;

        }

    } else {

        /* We have no lookahead info, so just use same type as the previous sequence. */

        uselongblock = !(prev_type == EIGHT_SHORT_SEQUENCE);

    }

    lame_apply_block_type(pch, &wi, uselongblock);

    wi.window_type[1] = prev_type;

    if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) {

        wi.num_windows  = 1;

        wi.grouping[0]  = 1;

        if (wi.window_type[0] == LONG_START_SEQUENCE)

            wi.window_shape = 0;

        else

            wi.window_shape = 1;

    } else {

        int lastgrp = 0;

        wi.num_windows = 8;

        wi.window_shape = 0;

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

            if (!((pch->next_grouping >> i) & 1))

                lastgrp = i;

            wi.grouping[lastgrp]++;

        }

    }

    /* Determine grouping, based on the location of the first attack, and save for

     * the next frame.

     * FIXME: Move this to analysis.

     * TODO: Tune groupings depending on attack location

     * TODO: Handle more than one attack in a group

     */

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

        if (attacks[i]) {

            grouping = i;

            break;

        }

    }

    pch->next_grouping = window_grouping[grouping];

    pch->prev_attack = attacks[8];

    return wi;

}


static void float_to_int16_stride_altivec(int16_t *dst, const float *src,

                                          long len, int stride)

{

    int i, j;

    vector signed short d, s;

    for (i = 0; i < len - 7; i += 8) {

        d = float_to_int16_one_altivec(src + i);

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

            s = vec_splat(d, j);

            vec_ste(s, 0, dst);

            dst += stride;

        }

    }

}


static int blk_connect(struct XenDevice *xendev)

{

    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);

    int pers, index, qflags;

    bool readonly = true;

    /* read-only ? */

    if (blkdev->directiosafe) {

        qflags = BDRV_O_NOCACHE | BDRV_O_NATIVE_AIO;

    } else {

        qflags = BDRV_O_CACHE_WB;

    }

    if (strcmp(blkdev->mode, "w") == 0) {

        qflags |= BDRV_O_RDWR;

        readonly = false;

    }

    if (blkdev->feature_discard) {

        qflags |= BDRV_O_UNMAP;

    }

    /* init qemu block driver */

    index = (blkdev->xendev.dev - 202 * 256) / 16;

    blkdev->dinfo = drive_get(IF_XEN, 0, index);

    if (!blkdev->dinfo) {

        Error *local_err = NULL;

        /* setup via xenbus -> create new block driver instance */

        xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");

        blkdev->bs = bdrv_new(blkdev->dev, &local_err);

        if (local_err) {

            blkdev->bs = NULL;

        }

        if (blkdev->bs) {

            BlockDriver *drv = bdrv_find_whitelisted_format(blkdev->fileproto,

                                                           readonly);

            if (bdrv_open(&blkdev->bs, blkdev->filename, NULL, NULL, qflags,

                          drv, &local_err) != 0)

            {

                xen_be_printf(&blkdev->xendev, 0, "error: %s\n",

                              error_get_pretty(local_err));

                error_free(local_err);

                bdrv_unref(blkdev->bs);

                blkdev->bs = NULL;

            }

        }

        if (!blkdev->bs) {

            return -1;

        }

    } else {

        /* setup via qemu cmdline -> already setup for us */

        xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");

        blkdev->bs = blkdev->dinfo->bdrv;

        if (bdrv_is_read_only(blkdev->bs) && !readonly) {

            xen_be_printf(&blkdev->xendev, 0, "Unexpected read-only drive");

            blkdev->bs = NULL;

            return -1;

        }

        /* blkdev->bs is not create by us, we get a reference

         * so we can bdrv_unref() unconditionally */

        bdrv_ref(blkdev->bs);

    }

    bdrv_attach_dev_nofail(blkdev->bs, blkdev);

    blkdev->file_size = bdrv_getlength(blkdev->bs);

    if (blkdev->file_size < 0) {

        xen_be_printf(&blkdev->xendev, 1, "bdrv_getlength: %d (%s) | drv %s\n",

                      (int)blkdev->file_size, strerror(-blkdev->file_size),

                      bdrv_get_format_name(blkdev->bs) ?: "-");

        blkdev->file_size = 0;

    }

    xen_be_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","

                  " size %" PRId64 " (%" PRId64 " MB)\n",

                  blkdev->type, blkdev->fileproto, blkdev->filename,

                  blkdev->file_size, blkdev->file_size >> 20);

    /* Fill in number of sector size and number of sectors */

    xenstore_write_be_int(&blkdev->xendev, "sector-size", blkdev->file_blk);

    xenstore_write_be_int64(&blkdev->xendev, "sectors",

                            blkdev->file_size / blkdev->file_blk);

    if (xenstore_read_fe_int(&blkdev->xendev, "ring-ref", &blkdev->ring_ref) == -1) {

        return -1;

    }

    if (xenstore_read_fe_int(&blkdev->xendev, "event-channel",

                             &blkdev->xendev.remote_port) == -1) {

        return -1;

    }

    if (xenstore_read_fe_int(&blkdev->xendev, "feature-persistent", &pers)) {

        blkdev->feature_persistent = FALSE;

    } else {

        blkdev->feature_persistent = !!pers;

    }

    blkdev->protocol = BLKIF_PROTOCOL_NATIVE;

    if (blkdev->xendev.protocol) {

        if (strcmp(blkdev->xendev.protocol, XEN_IO_PROTO_ABI_X86_32) == 0) {

            blkdev->protocol = BLKIF_PROTOCOL_X86_32;

        }

        if (strcmp(blkdev->xendev.protocol, XEN_IO_PROTO_ABI_X86_64) == 0) {

            blkdev->protocol = BLKIF_PROTOCOL_X86_64;

        }

    }

    blkdev->sring = xc_gnttab_map_grant_ref(blkdev->xendev.gnttabdev,

                                            blkdev->xendev.dom,

                                            blkdev->ring_ref,

                                            PROT_READ | PROT_WRITE);

    if (!blkdev->sring) {

        return -1;

    }

    blkdev->cnt_map++;

    switch (blkdev->protocol) {

    case BLKIF_PROTOCOL_NATIVE:

    {

        blkif_sring_t *sring_native = blkdev->sring;

        BACK_RING_INIT(&blkdev->rings.native, sring_native, XC_PAGE_SIZE);

        break;

    }

    case BLKIF_PROTOCOL_X86_32:

    {

        blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;

        BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32, XC_PAGE_SIZE);

        break;

    }

    case BLKIF_PROTOCOL_X86_64:

    {

        blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;

        BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, XC_PAGE_SIZE);

        break;

    }

    }

    if (blkdev->feature_persistent) {

        /* Init persistent grants */

        blkdev->max_grants = max_requests * BLKIF_MAX_SEGMENTS_PER_REQUEST;

        blkdev->persistent_gnts = g_tree_new_full((GCompareDataFunc)int_cmp,

                                             NULL, NULL,

                                             (GDestroyNotify)destroy_grant);

        blkdev->persistent_gnt_count = 0;

    }

    xen_be_bind_evtchn(&blkdev->xendev);

    xen_be_printf(&blkdev->xendev, 1, "ok: proto %s, ring-ref %d, "

                  "remote port %d, local port %d\n",

                  blkdev->xendev.protocol, blkdev->ring_ref,

                  blkdev->xendev.remote_port, blkdev->xendev.local_port);

    return 0;

}


static void vp3_idct_dc_add_c(uint8_t *dest/*align 8*/, int line_size,

                              const DCTELEM *block/*align 16*/){

    int i, dc = (block[0] + 15) >> 5;

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

        dest[0] = av_clip_uint8(dest[0] + dc);

        dest[1] = av_clip_uint8(dest[1] + dc);

        dest[2] = av_clip_uint8(dest[2] + dc);

        dest[3] = av_clip_uint8(dest[3] + dc);

        dest[4] = av_clip_uint8(dest[4] + dc);

        dest[5] = av_clip_uint8(dest[5] + dc);

        dest[6] = av_clip_uint8(dest[6] + dc);

        dest[7] = av_clip_uint8(dest[7] + dc);

        dest += line_size;

    }

}


static void usb_net_handle_destroy(USBDevice *dev)

{

    USBNetState *s = (USBNetState *) dev;

    /* TODO: remove the nd_table[] entry */

    qemu_del_vlan_client(s->vc);

    rndis_clear_responsequeue(s);

    qemu_free(s);

}


static av_cold int libopenjpeg_encode_close(AVCodecContext *avctx)

{

    LibOpenJPEGContext *ctx = avctx->priv_data;

    opj_cio_close(ctx->stream);

    ctx->stream = NULL;

    opj_destroy_compress(ctx->compress);

    ctx->compress = NULL;

    opj_image_destroy(ctx->image);

    ctx->image = NULL;

    av_freep(&avctx->coded_frame);

    return 0;

}


FFAMediaFormat *ff_AMediaFormat_new(void)

{

    JNIEnv *env = NULL;

    FFAMediaFormat *format = NULL;

    format = av_mallocz(sizeof(FFAMediaFormat));

    if (!format) {

        return NULL;

    }

    format->class = &amediaformat_class;

    env = ff_jni_get_env(format);

    if (!env) {

        av_freep(&format);

        return NULL;

    }

    if (ff_jni_init_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format) < 0) {

        goto fail;

    }

    format->object = (*env)->NewObject(env, format->jfields.mediaformat_class, format->jfields.init_id);

    if (!format->object) {

        goto fail;

    }

    format->object = (*env)->NewGlobalRef(env, format->object);

    if (!format->object) {

        goto fail;

    }

    return format;

fail:

    ff_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format);

    av_freep(&format);

    return NULL;

}


static int deband_8_coupling_c(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)

{

    DebandContext *s = ctx->priv;

    ThreadData *td = arg;

    AVFrame *in = td->in;

    AVFrame *out = td->out;

    const int start = (s->planeheight[0] *  jobnr   ) / nb_jobs;

    const int end   = (s->planeheight[0] * (jobnr+1)) / nb_jobs;

    int x, y, p;

    for (y = start; y < end; y++) {

        const int pos = y * s->planewidth[0];

        for (x = 0; x < s->planewidth[p]; x++) {

            const int x_pos = s->x_pos[pos + x];

            const int y_pos = s->y_pos[pos + x];

            int avg[4], cmp[4] = { 0 }, src[4];

            for (p = 0; p < s->nb_components; p++) {

                const uint8_t *src_ptr = (const uint8_t *)in->data[p];

                const int src_linesize = in->linesize[p];

                const int thr = s->thr[p];

                const int w = s->planewidth[p] - 1;

                const int h = s->planeheight[p] - 1;

                const int ref0 = src_ptr[av_clip(y +  y_pos, 0, h) * src_linesize + av_clip(x +  x_pos, 0, w)];

                const int ref1 = src_ptr[av_clip(y + -y_pos, 0, h) * src_linesize + av_clip(x +  x_pos, 0, w)];

                const int ref2 = src_ptr[av_clip(y + -y_pos, 0, h) * src_linesize + av_clip(x + -x_pos, 0, w)];

                const int ref3 = src_ptr[av_clip(y +  y_pos, 0, h) * src_linesize + av_clip(x + -x_pos, 0, w)];

                const int src0 = src_ptr[y * src_linesize + x];

                src[p] = src0;

                avg[p] = get_avg(ref0, ref1, ref2, ref3);

                if (s->blur) {

                    cmp[p] = FFABS(src0 - avg[p]) < thr;

                } else {

                    cmp[p] = (FFABS(src0 - ref0) < thr) &&

                             (FFABS(src0 - ref1) < thr) &&

                             (FFABS(src0 - ref2) < thr) &&

                             (FFABS(src0 - ref3) < thr);

                }

            }

            for (p = 0; p < s->nb_components; p++)

                if (!cmp[p])

                    break;

            if (p == s->nb_components) {

                for (p = 0; p < s->nb_components; p++) {

                    const int dst_linesize = out->linesize[p];

                    out->data[p][y * dst_linesize + x] = avg[p];

                }

            } else {

                for (p = 0; p < s->nb_components; p++) {

                    const int dst_linesize = out->linesize[p];

                    out->data[p][y * dst_linesize + x] = src[p];

                }

            }

        }

    }

    return 0;

}


int qemu_egl_rendernode_open(void)

{

    DIR *dir;

    struct dirent *e;

    int r, fd;

    char *p;

    dir = opendir("/dev/dri");

    if (!dir) {

        return -1;

    }

    fd = -1;

    while ((e = readdir(dir))) {

        if (e->d_type != DT_CHR) {

            continue;

        }

        if (strncmp(e->d_name, "renderD", 7)) {

            continue;

        }

        r = asprintf(&p, "/dev/dri/%s", e->d_name);

        if (r < 0) {

            return -1;

        }

        r = open(p, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);

        if (r < 0) {

            free(p);

            continue;

        }

        fd = r;

        free(p);

        break;

    }

    closedir(dir);

    if (fd < 0) {

        return -1;

    }

    return fd;

}


void qemu_check_nic_model(NICInfo *nd, const char *model)

{

    const char *models[2];

    models[0] = model;

    models[1] = NULL;

    qemu_check_nic_model_list(nd, models, model);

}


int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)

{

    int i, ret;

    Picture *pic;

    s->mb_skipped = 0;

    if (!ff_thread_can_start_frame(avctx)) {

        av_log(avctx, AV_LOG_ERROR, "Attempt to start a frame outside SETUP state\n");

        return -1;

    }

    /* mark & release old frames */

    if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr &&

        s->last_picture_ptr != s->next_picture_ptr &&

        s->last_picture_ptr->f->buf[0]) {

        ff_mpeg_unref_picture(s, s->last_picture_ptr);

    }

    /* release forgotten pictures */

    /* if (mpeg124/h263) */

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

        if (&s->picture[i] != s->last_picture_ptr &&

            &s->picture[i] != s->next_picture_ptr &&

            s->picture[i].reference && !s->picture[i].needs_realloc) {

            if (!(avctx->active_thread_type & FF_THREAD_FRAME))

                av_log(avctx, AV_LOG_ERROR,

                       "releasing zombie picture\n");

            ff_mpeg_unref_picture(s, &s->picture[i]);

        }

    }

    ff_mpeg_unref_picture(s, &s->current_picture);

    release_unused_pictures(s);

    if (s->current_picture_ptr &&

        s->current_picture_ptr->f->buf[0] == NULL) {

        // we already have a unused image

        // (maybe it was set before reading the header)

        pic = s->current_picture_ptr;

    } else {

        i   = ff_find_unused_picture(s, 0);

        if (i < 0) {

            av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n");

            return i;

        }

        pic = &s->picture[i];

    }

    pic->reference = 0;

    if (!s->droppable) {

        if (s->pict_type != AV_PICTURE_TYPE_B)

            pic->reference = 3;

    }

    pic->f->coded_picture_number = s->coded_picture_number++;

    if (ff_alloc_picture(s, pic, 0) < 0)

        return -1;

    s->current_picture_ptr = pic;

    // FIXME use only the vars from current_pic

    s->current_picture_ptr->f->top_field_first = s->top_field_first;

    if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO ||

        s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {

        if (s->picture_structure != PICT_FRAME)

            s->current_picture_ptr->f->top_field_first =

                (s->picture_structure == PICT_TOP_FIELD) == s->first_field;

    }

    s->current_picture_ptr->f->interlaced_frame = !s->progressive_frame &&

                                                 !s->progressive_sequence;

    s->current_picture_ptr->field_picture      =  s->picture_structure != PICT_FRAME;

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

    // if (s->flags && CODEC_FLAG_QSCALE)

    //     s->current_picture_ptr->quality = s->new_picture_ptr->quality;

    s->current_picture_ptr->f->key_frame = s->pict_type == AV_PICTURE_TYPE_I;

    if ((ret = ff_mpeg_ref_picture(s, &s->current_picture,

                                   s->current_picture_ptr)) < 0)

        return ret;

    if (s->pict_type != AV_PICTURE_TYPE_B) {

        s->last_picture_ptr = s->next_picture_ptr;

        if (!s->droppable)

            s->next_picture_ptr = s->current_picture_ptr;

    }

    av_dlog(s->avctx, "L%p N%p C%p L%p N%p C%p type:%d drop:%d\n",

            s->last_picture_ptr, s->next_picture_ptr,s->current_picture_ptr,

            s->last_picture_ptr    ? s->last_picture_ptr->f->data[0]    : NULL,

            s->next_picture_ptr    ? s->next_picture_ptr->f->data[0]    : NULL,

            s->current_picture_ptr ? s->current_picture_ptr->f->data[0] : NULL,

            s->pict_type, s->droppable);

    if ((s->last_picture_ptr == NULL ||

         s->last_picture_ptr->f->buf[0] == NULL) &&

        (s->pict_type != AV_PICTURE_TYPE_I ||

         s->picture_structure != PICT_FRAME)) {

        int h_chroma_shift, v_chroma_shift;

        av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,

                                         &h_chroma_shift, &v_chroma_shift);

        if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture_ptr && s->next_picture_ptr->f->buf[0])

            av_log(avctx, AV_LOG_DEBUG,

                   "allocating dummy last picture for B frame\n");

        else if (s->pict_type != AV_PICTURE_TYPE_I)

            av_log(avctx, AV_LOG_ERROR,

                   "warning: first frame is no keyframe\n");

        else if (s->picture_structure != PICT_FRAME)

            av_log(avctx, AV_LOG_DEBUG,

                   "allocate dummy last picture for field based first keyframe\n");

        /* Allocate a dummy frame */

        i = ff_find_unused_picture(s, 0);

        if (i < 0) {

            av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n");

            return i;

        }

        s->last_picture_ptr = &s->picture[i];

        s->last_picture_ptr->reference   = 3;

        s->last_picture_ptr->f->key_frame = 0;

        s->last_picture_ptr->f->pict_type = AV_PICTURE_TYPE_P;

        if (ff_alloc_picture(s, s->last_picture_ptr, 0) < 0) {

            s->last_picture_ptr = NULL;

            return -1;

        }

        if (!avctx->hwaccel) {

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

                memset(s->last_picture_ptr->f->data[0] + s->last_picture_ptr->f->linesize[0]*i,

                       0x80, avctx->width);

            for(i=0; i<FF_CEIL_RSHIFT(avctx->height, v_chroma_shift); i++) {

                memset(s->last_picture_ptr->f->data[1] + s->last_picture_ptr->f->linesize[1]*i,

                       0x80, FF_CEIL_RSHIFT(avctx->width, h_chroma_shift));

                memset(s->last_picture_ptr->f->data[2] + s->last_picture_ptr->f->linesize[2]*i,

                       0x80, FF_CEIL_RSHIFT(avctx->width, h_chroma_shift));

            }

            if(s->codec_id == AV_CODEC_ID_FLV1 || s->codec_id == AV_CODEC_ID_H263){

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

                memset(s->last_picture_ptr->f->data[0] + s->last_picture_ptr->f->linesize[0]*i, 16, avctx->width);

            }

        }

        ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 0);

        ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 1);

    }

    if ((s->next_picture_ptr == NULL ||

         s->next_picture_ptr->f->buf[0] == NULL) &&

        s->pict_type == AV_PICTURE_TYPE_B) {

        /* Allocate a dummy frame */

        i = ff_find_unused_picture(s, 0);

        if (i < 0) {

            av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n");

            return i;

        }

        s->next_picture_ptr = &s->picture[i];

        s->next_picture_ptr->reference   = 3;

        s->next_picture_ptr->f->key_frame = 0;

        s->next_picture_ptr->f->pict_type = AV_PICTURE_TYPE_P;

        if (ff_alloc_picture(s, s->next_picture_ptr, 0) < 0) {

            s->next_picture_ptr = NULL;

            return -1;

        }

        ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 0);

        ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 1);

    }

#if 0 // BUFREF-FIXME

    memset(s->last_picture.f->data, 0, sizeof(s->last_picture.f->data));

    memset(s->next_picture.f->data, 0, sizeof(s->next_picture.f->data));

#endif

    if (s->last_picture_ptr) {

        ff_mpeg_unref_picture(s, &s->last_picture);

        if (s->last_picture_ptr->f->buf[0] &&

            (ret = ff_mpeg_ref_picture(s, &s->last_picture,

                                       s->last_picture_ptr)) < 0)

            return ret;

    }

    if (s->next_picture_ptr) {

        ff_mpeg_unref_picture(s, &s->next_picture);

        if (s->next_picture_ptr->f->buf[0] &&

            (ret = ff_mpeg_ref_picture(s, &s->next_picture,

                                       s->next_picture_ptr)) < 0)

            return ret;

    }

    av_assert0(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr &&

                                                 s->last_picture_ptr->f->buf[0]));

    if (s->picture_structure!= PICT_FRAME) {

        int i;

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

            if (s->picture_structure == PICT_BOTTOM_FIELD) {

                s->current_picture.f->data[i] +=

                    s->current_picture.f->linesize[i];

            }

            s->current_picture.f->linesize[i] *= 2;

            s->last_picture.f->linesize[i]    *= 2;

            s->next_picture.f->linesize[i]    *= 2;

        }

    }

    s->err_recognition = avctx->err_recognition;

    /* set dequantizer, we can't do it during init as

     * it might change for mpeg4 and we can't do it in the header

     * decode as init is not called for mpeg4 there yet */

    if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {

        s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra;

        s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter;

    } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {

        s->dct_unquantize_intra = s->dct_unquantize_h263_intra;

        s->dct_unquantize_inter = s->dct_unquantize_h263_inter;

    } else {

        s->dct_unquantize_intra = s->dct_unquantize_mpeg1_intra;

        s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter;

    }

    return 0;

}


static void test_identify(void)

{

    uint8_t data;

    uint16_t buf[256];

    int i;

    int ret;

    ide_test_start(

        "-vnc none "

        "-drive file=%s,if=ide,serial=%s,cache=writeback "

        "-global ide-hd.ver=%s",

        tmp_path, "testdisk", "version");

    /* IDENTIFY command on device 0*/

    outb(IDE_BASE + reg_device, 0);

    outb(IDE_BASE + reg_command, CMD_IDENTIFY);

    /* Read in the IDENTIFY buffer and check registers */

    data = inb(IDE_BASE + reg_device);

    g_assert_cmpint(data & DEV, ==, 0);

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

        data = inb(IDE_BASE + reg_status);

        assert_bit_set(data, DRDY | DRQ);

        assert_bit_clear(data, BSY | DF | ERR);

        ((uint16_t*) buf)[i] = inw(IDE_BASE + reg_data);

    }

    data = inb(IDE_BASE + reg_status);

    assert_bit_set(data, DRDY);

    assert_bit_clear(data, BSY | DF | ERR | DRQ);

    /* Check serial number/version in the buffer */

    string_cpu_to_be16(&buf[10], 20);

    ret = memcmp(&buf[10], "testdisk            ", 20);

    g_assert(ret == 0);

    string_cpu_to_be16(&buf[23], 8);

    ret = memcmp(&buf[23], "version ", 8);

    g_assert(ret == 0);

    /* Write cache enabled bit */

    assert_bit_set(buf[85], 0x20);

    ide_test_quit();

}


static void gen_window_check2(DisasContext *dc, unsigned r1, unsigned r2)

{

    gen_window_check1(dc, r1 > r2 ? r1 : r2);

}


static int decode_0(AVCodecContext *avctx, uint8_t code, uint8_t *pkt)

{

    PAFVideoDecContext *c = avctx->priv_data;

    uint32_t opcode_size, offset;

    uint8_t *dst, *dend, mask = 0, color = 0, a, b, p;

    const uint8_t *src, *send, *opcodes;

    int  i, j, x = 0;

    i = bytestream2_get_byte(&c->gb);

    if (i) {

        if (code & 0x10) {

            int align;

            align = bytestream2_tell(&c->gb) & 3;

            if (align)

                bytestream2_skip(&c->gb, 4 - align);

        }

        do {

            a      = bytestream2_get_byte(&c->gb);

            b      = bytestream2_get_byte(&c->gb);

            p      = (a & 0xC0) >> 6;

            dst    = c->frame[p] + get_video_page_offset(avctx, a, b);

            dend   = c->frame[p] + c->frame_size;

            offset = (b & 0x7F) * 2;

            j      = bytestream2_get_le16(&c->gb) + offset;

            do {

                offset++;

                if (dst + 3 * avctx->width + 4 > dend)

                    return AVERROR_INVALIDDATA;

                copy4h(avctx, dst);

                if ((offset & 0x3F) == 0)

                    dst += avctx->width * 3;

                dst += 4;

            } while (offset < j);

        } while (--i);

    }

    dst = c->frame[c->current_frame];

    do {

        a    = bytestream2_get_byte(&c->gb);

        b    = bytestream2_get_byte(&c->gb);

        p    = (a & 0xC0) >> 6;

        src  = c->frame[p] + get_video_page_offset(avctx, a, b);

        send = c->frame[p] + c->frame_size;

        if (src + 3 * avctx->width + 4 > send)

            return AVERROR_INVALIDDATA;

        copy_block4(dst, src, avctx->width, avctx->width, 4);

        i++;

        if ((i & 0x3F) == 0)

            dst += avctx->width * 3;

        dst += 4;

    } while (i < c->video_size / 16);

    opcode_size = bytestream2_get_le16(&c->gb);

    bytestream2_skip(&c->gb, 2);

    if (bytestream2_get_bytes_left(&c->gb) < opcode_size)

        return AVERROR_INVALIDDATA;

    opcodes = pkt + bytestream2_tell(&c->gb);

    bytestream2_skipu(&c->gb, opcode_size);

    dst = c->frame[c->current_frame];

    for (i = 0; i < avctx->height; i += 4, dst += avctx->width * 3) {

        for (j = 0; j < avctx->width; j += 4, dst += 4) {

            int opcode, k = 0;

            if (x > opcode_size)

                return AVERROR_INVALIDDATA;

            if (j & 4) {

                opcode = opcodes[x] & 15;

                x++;

            } else {

                opcode = opcodes[x] >> 4;

            }

            while (block_sequences[opcode][k]) {

                offset = avctx->width * 2;

                code   = block_sequences[opcode][k++];

                switch (code) {

                case 2:

                    offset = 0;

                case 3:

                    color  = bytestream2_get_byte(&c->gb);

                case 4:

                    mask   = bytestream2_get_byte(&c->gb);

                    copy_color_mask(avctx, mask, dst + offset, color);

                    break;

                case 5:

                    offset = 0;

                case 6:

                    a    = bytestream2_get_byte(&c->gb);

                    b    = bytestream2_get_byte(&c->gb);

                    p    = (a & 0xC0) >> 6;

                    src  = c->frame[p] + get_video_page_offset(avctx, a, b);

                    send = c->frame[p] + c->frame_size;

                case 7:

                    if (src + offset + avctx->width + 4 > send)

                        return AVERROR_INVALIDDATA;

                    mask = bytestream2_get_byte(&c->gb);

                    copy_src_mask(avctx, mask, dst + offset, src + offset);

                    break;

                }

            }

        }

    }

    return 0;

}


static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,

                                  int64_t *pos_arg, int64_t pos_limit)

{

    struct ogg *ogg = s->priv_data;

    struct ogg_stream *os = ogg->streams + stream_index;

    AVIOContext *bc = s->pb;

    int64_t pts = AV_NOPTS_VALUE;

    int i;

    avio_seek(bc, *pos_arg, SEEK_SET);

    ogg_reset(ogg);

    while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {

        if (i == stream_index) {

            pts = ogg_calc_pts(s, i, NULL);

            if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))

                pts = AV_NOPTS_VALUE;

        }

        if (pts != AV_NOPTS_VALUE)

            break;

    }

    ogg_reset(ogg);

    return pts;

}


static int scaling_list_data(GetBitContext *gb, AVCodecContext *avctx, ScalingList *sl, HEVCSPS *sps)

{

    uint8_t scaling_list_pred_mode_flag;

    int32_t scaling_list_dc_coef[2][6];

    int size_id, matrix_id, pos;

    int i;

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

        for (matrix_id = 0; matrix_id < 6; matrix_id += ((size_id == 3) ? 3 : 1)) {

            scaling_list_pred_mode_flag = get_bits1(gb);

            if (!scaling_list_pred_mode_flag) {

                unsigned int delta = get_ue_golomb_long(gb);

                /* Only need to handle non-zero delta. Zero means default,

                 * which should already be in the arrays. */

                if (delta) {

                    // Copy from previous array.

                    if (matrix_id < delta) {

                        av_log(avctx, AV_LOG_ERROR,

                               "Invalid delta in scaling list data: %d.\n", delta);

                        return AVERROR_INVALIDDATA;

                    }

                    memcpy(sl->sl[size_id][matrix_id],

                           sl->sl[size_id][matrix_id - delta],

                           size_id > 0 ? 64 : 16);

                    if (size_id > 1)

                        sl->sl_dc[size_id - 2][matrix_id] = sl->sl_dc[size_id - 2][matrix_id - delta];

                }

            } else {

                int next_coef, coef_num;

                int32_t scaling_list_delta_coef;

                next_coef = 8;

                coef_num  = FFMIN(64, 1 << (4 + (size_id << 1)));

                if (size_id > 1) {

                    scaling_list_dc_coef[size_id - 2][matrix_id] = get_se_golomb(gb) + 8;

                    next_coef = scaling_list_dc_coef[size_id - 2][matrix_id];

                    sl->sl_dc[size_id - 2][matrix_id] = next_coef;

                }

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

                    if (size_id == 0)

                        pos = 4 * ff_hevc_diag_scan4x4_y[i] +

                                  ff_hevc_diag_scan4x4_x[i];

                    else

                        pos = 8 * ff_hevc_diag_scan8x8_y[i] +

                                  ff_hevc_diag_scan8x8_x[i];

                    scaling_list_delta_coef = get_se_golomb(gb);

                    next_coef = (next_coef + scaling_list_delta_coef + 256) % 256;

                    sl->sl[size_id][matrix_id][pos] = next_coef;

                }

            }

        }

    if (sps->chroma_format_idc == 3) {

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

            sl->sl[3][1][i] = sl->sl[2][1][i];

            sl->sl[3][2][i] = sl->sl[2][2][i];

            sl->sl[3][4][i] = sl->sl[2][4][i];

            sl->sl[3][5][i] = sl->sl[2][5][i];

        }

        sl->sl_dc[1][1] = sl->sl_dc[0][1];

        sl->sl_dc[1][2] = sl->sl_dc[0][2];

        sl->sl_dc[1][4] = sl->sl_dc[0][4];

        sl->sl_dc[1][5] = sl->sl_dc[0][5];

    }

    return 0;

}


static int recode_subtitle(AVCodecContext *avctx,

                           AVPacket *outpkt, const AVPacket *inpkt)

{

#if CONFIG_ICONV

    iconv_t cd = (iconv_t)-1;

    int ret = 0;

    char *inb, *outb;

    size_t inl, outl;

    AVPacket tmp;

#endif

    if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER)

        return 0;

#if CONFIG_ICONV

    cd = iconv_open("UTF-8", avctx->sub_charenc);

    av_assert0(cd != (iconv_t)-1);

    inb = inpkt->data;

    inl = inpkt->size;

    if (inl >= INT_MAX / UTF8_MAX_BYTES - FF_INPUT_BUFFER_PADDING_SIZE) {

        av_log(avctx, AV_LOG_ERROR, "Subtitles packet is too big for recoding\n");

        ret = AVERROR(ENOMEM);

        goto end;

    }

    ret = av_new_packet(&tmp, inl * UTF8_MAX_BYTES);

    if (ret < 0)

        goto end;

    outpkt->buf  = tmp.buf;

    outpkt->data = tmp.data;

    outpkt->size = tmp.size;

    outb = outpkt->data;

    outl = outpkt->size;

    if (iconv(cd, &inb, &inl, &outb, &outl) == (size_t)-1 ||

        iconv(cd, NULL, NULL, &outb, &outl) == (size_t)-1 ||

        outl >= outpkt->size || inl != 0) {

        av_log(avctx, AV_LOG_ERROR, "Unable to recode subtitle event \"%s\" "

               "from %s to UTF-8\n", inpkt->data, avctx->sub_charenc);

        av_free_packet(&tmp);

        ret = AVERROR(errno);

        goto end;

    }

    outpkt->size -= outl;

    outpkt->data[outpkt->size - 1] = '\0';

end:

    if (cd != (iconv_t)-1)

        iconv_close(cd);

    return ret;

#else

    av_assert0(!"requesting subtitles recoding without iconv");

#endif

}


void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment)

{

    size_t align = QEMU_VMALLOC_ALIGN;

    size_t total = size + align - getpagesize();

    void *ptr = mmap(0, total, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);

    size_t offset = QEMU_ALIGN_UP((uintptr_t)ptr, align) - (uintptr_t)ptr;

    void *ptr1;

    if (ptr == MAP_FAILED) {

        return NULL;

    }

    if (alignment) {

        *alignment = align;

    }

    ptr1 = mmap(ptr + offset, size, PROT_READ | PROT_WRITE,

                MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);

    if (ptr1 == MAP_FAILED) {

        munmap(ptr, total);

        return NULL;

    }

    ptr += offset;

    total -= offset;

    if (offset > 0) {

        munmap(ptr - offset, offset);

    }

    if (total > size) {

        munmap(ptr + size, total - size);

    }

    trace_qemu_anon_ram_alloc(size, ptr);

    return ptr;

}


void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)

{

    int i, r;

    for (i = 0; i < hdev->nvqs; ++i) {

        vhost_virtqueue_cleanup(hdev,

                                vdev,

                                hdev->vqs + i,

                                i);

    }

    vhost_client_sync_dirty_bitmap(&hdev->client, 0,

                                   (target_phys_addr_t)~0x0ull);

    r = vdev->binding->set_guest_notifiers(vdev->binding_opaque, false);

    if (r < 0) {

        fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r);

        fflush(stderr);

    }

    assert (r >= 0);

    hdev->started = false;

    g_free(hdev->log);

    hdev->log = NULL;

    hdev->log_size = 0;

}


static int ffm_read_data(AVFormatContext *s,

                         uint8_t *buf, int size, int first)

{

    FFMContext *ffm = s->priv_data;

    ByteIOContext *pb = s->pb;

    int len, fill_size, size1, frame_offset;

    size1 = size;

    while (size > 0) {

    redo:

        len = ffm->packet_end - ffm->packet_ptr;

        if (len < 0)

            return -1;

        if (len > size)

            len = size;

        if (len == 0) {

            if (url_ftell(pb) == ffm->file_size)

                url_fseek(pb, ffm->packet_size, SEEK_SET);

    retry_read:

            get_be16(pb); /* PACKET_ID */

            fill_size = get_be16(pb);

            ffm->pts = get_be64(pb);

            ffm->first_frame_in_packet = 1;

            frame_offset = get_be16(pb);

            get_buffer(pb, ffm->packet, ffm->packet_size - FFM_HEADER_SIZE);

            ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size);

            if (ffm->packet_end < ffm->packet)

                return -1;

            /* if first packet or resynchronization packet, we must

               handle it specifically */

            if (ffm->first_packet || (frame_offset & 0x8000)) {

                if (!frame_offset) {

                    /* This packet has no frame headers in it */

                    if (url_ftell(pb) >= ffm->packet_size * 3) {

                        url_fseek(pb, -ffm->packet_size * 2, SEEK_CUR);

                        goto retry_read;

                    }

                    /* This is bad, we cannot find a valid frame header */

                    return 0;

                }

                ffm->first_packet = 0;

                if ((frame_offset & 0x7ffff) < FFM_HEADER_SIZE)

                    return -1;

                ffm->packet_ptr = ffm->packet + (frame_offset & 0x7fff) - FFM_HEADER_SIZE;

                if (!first)

                    break;

            } else {

                ffm->packet_ptr = ffm->packet;

            }

            goto redo;

        }

        memcpy(buf, ffm->packet_ptr, len);

        buf += len;

        ffm->packet_ptr += len;

        size -= len;

        first = 0;

    }

    return size1 - size;

}


static int mpegts_write_section1(MpegTSSection *s, int tid, int id,

                                 int version, int sec_num, int last_sec_num,

                                 uint8_t *buf, int len)

{

    uint8_t section[1024], *q;

    unsigned int tot_len;

    /* reserved_future_use field must be set to 1 for SDT */

    unsigned int flags = tid == SDT_TID ? 0xf000 : 0xb000;

    tot_len = 3 + 5 + len + 4;

    /* check if not too big */

    if (tot_len > 1024)

        return -1;

    q    = section;

    *q++ = tid;

    put16(&q, flags | (len + 5 + 4)); /* 5 byte header + 4 byte CRC */

    put16(&q, id);

    *q++ = 0xc1 | (version << 1); /* current_next_indicator = 1 */

    *q++ = sec_num;

    *q++ = last_sec_num;

    memcpy(q, buf, len);

    mpegts_write_section(s, section, tot_len);

    return 0;

}


static int compare_doubles(const double *a, const double *b, int len,

                           double max_diff)

{

    int i;

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

        if (fabs(a[i] - b[i]) > max_diff) {

            av_log(NULL, AV_LOG_ERROR, "%d: %- .12f - %- .12f = % .12g\n",

                   i, a[i], b[i], a[i] - b[i]);

            return -1;

        }

    }

    return 0;

}


static int fourxm_read_header(AVFormatContext *s,

                              AVFormatParameters *ap)

{

    ByteIOContext *pb = s->pb;

    unsigned int fourcc_tag;

    unsigned int size;

    int header_size;

    FourxmDemuxContext *fourxm = s->priv_data;

    unsigned char *header;

    int i;

    int current_track = -1;

    AVStream *st;

    fourxm->track_count = 0;

    fourxm->tracks = NULL;

    fourxm->selected_track = 0;

    fourxm->fps = 1.0;

    /* skip the first 3 32-bit numbers */

    url_fseek(pb, 12, SEEK_CUR);

    /* check for LIST-HEAD */

    GET_LIST_HEADER();

    header_size = size - 4;

    if (fourcc_tag != HEAD_TAG || size < 4)

        return AVERROR_INVALIDDATA;

    /* allocate space for the header and load the whole thing */

    header = av_malloc(header_size);

    if (!header)

        return AVERROR(ENOMEM);

    if (get_buffer(pb, header, header_size) != header_size)

        return AVERROR(EIO);

    /* take the lazy approach and search for any and all vtrk and strk chunks */

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

        fourcc_tag = AV_RL32(&header[i]);

        size = AV_RL32(&header[i + 4]);

        if (fourcc_tag == std__TAG) {

            fourxm->fps = av_int2flt(AV_RL32(&header[i + 12]));

        } else if (fourcc_tag == vtrk_TAG) {

            /* check that there is enough data */

            if (size != vtrk_SIZE) {

                av_free(header);

                return AVERROR_INVALIDDATA;

            }

            fourxm->width = AV_RL32(&header[i + 36]);

            fourxm->height = AV_RL32(&header[i + 40]);

            /* allocate a new AVStream */

            st = av_new_stream(s, 0);

            if (!st)

                return AVERROR(ENOMEM);

            av_set_pts_info(st, 60, 1, fourxm->fps);

            fourxm->video_stream_index = st->index;

            st->codec->codec_type = CODEC_TYPE_VIDEO;

            st->codec->codec_id = CODEC_ID_4XM;

            st->codec->extradata_size = 4;

            st->codec->extradata = av_malloc(4);

            AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16]));

            st->codec->width = fourxm->width;

            st->codec->height = fourxm->height;

            i += 8 + size;

        } else if (fourcc_tag == strk_TAG) {

            /* check that there is enough data */

            if (size != strk_SIZE) {

                av_free(header);

                return AVERROR_INVALIDDATA;

            }

            current_track = AV_RL32(&header[i + 8]);

            if (current_track + 1 > fourxm->track_count) {

                fourxm->track_count = current_track + 1;

                if((unsigned)fourxm->track_count >= UINT_MAX / sizeof(AudioTrack))

                    return -1;

                fourxm->tracks = av_realloc(fourxm->tracks,

                    fourxm->track_count * sizeof(AudioTrack));

                if (!fourxm->tracks) {

                    av_free(header);

                    return AVERROR(ENOMEM);

                }

            }

            fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]);

            fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]);

            fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]);

            fourxm->tracks[current_track].bits = AV_RL32(&header[i + 44]);

            i += 8 + size;

            /* allocate a new AVStream */

            st = av_new_stream(s, current_track);

            if (!st)

                return AVERROR(ENOMEM);

            av_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate);

            fourxm->tracks[current_track].stream_index = st->index;

            st->codec->codec_type = CODEC_TYPE_AUDIO;

            st->codec->codec_tag = 0;

            st->codec->channels = fourxm->tracks[current_track].channels;

            st->codec->sample_rate = fourxm->tracks[current_track].sample_rate;

            st->codec->bits_per_coded_sample = fourxm->tracks[current_track].bits;

            st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *

                st->codec->bits_per_coded_sample;

            st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;

            if (fourxm->tracks[current_track].adpcm)

                st->codec->codec_id = CODEC_ID_ADPCM_4XM;

            else if (st->codec->bits_per_coded_sample == 8)

                st->codec->codec_id = CODEC_ID_PCM_U8;

            else

                st->codec->codec_id = CODEC_ID_PCM_S16LE;

        }

    }

    av_free(header);

    /* skip over the LIST-MOVI chunk (which is where the stream should be */

    GET_LIST_HEADER();

    if (fourcc_tag != MOVI_TAG)

        return AVERROR_INVALIDDATA;

    /* initialize context members */

    fourxm->video_pts = -1;  /* first frame will push to 0 */

    fourxm->audio_pts = 0;

    return 0;

}


static int flush_packet(AVFormatContext *ctx, int stream_index,

                         int64_t pts, int64_t dts, int64_t scr, int trailer_size)

{

    MpegMuxContext *s = ctx->priv_data;

    StreamInfo *stream = ctx->streams[stream_index]->priv_data;

    uint8_t *buf_ptr;

    int size, payload_size, startcode, id, stuffing_size, i, header_len;

    int packet_size;

    uint8_t buffer[128];

    int zero_trail_bytes = 0;

    int pad_packet_bytes = 0;

    int pes_flags;

    int general_pack = 0;  /*"general" pack without data specific to one stream?*/

    int nb_frames;

    id = stream->id;

#if 0

    printf("packet ID=%2x PTS=%0.3f\n",

           id, pts / 90000.0);

#endif

    buf_ptr = buffer;

    if ((s->packet_number % s->pack_header_freq) == 0 || s->last_scr != scr) {

        /* output pack and systems header if needed */

        size = put_pack_header(ctx, buf_ptr, scr);

        buf_ptr += size;

        s->last_scr= scr;

        if (s->is_vcd) {

            /* there is exactly one system header for each stream in a VCD MPEG,

               One in the very first video packet and one in the very first

               audio packet (see VCD standard p. IV-7 and IV-8).*/

            if (stream->packet_number==0) {

                size = put_system_header(ctx, buf_ptr, id);

                buf_ptr += size;

            }

        } else if (s->is_dvd) {

            if (stream->align_iframe || s->packet_number == 0){

                int PES_bytes_to_fill = s->packet_size - size - 10;

                if (pts != AV_NOPTS_VALUE) {

                    if (dts != pts)

                        PES_bytes_to_fill -= 5 + 5;

                    else

                        PES_bytes_to_fill -= 5;

                }

                if (stream->bytes_to_iframe == 0 || s->packet_number == 0) {

                    size = put_system_header(ctx, buf_ptr, 0);

                    buf_ptr += size;

                    size = buf_ptr - buffer;

                    put_buffer(ctx->pb, buffer, size);

                    put_be32(ctx->pb, PRIVATE_STREAM_2);

                    put_be16(ctx->pb, 0x03d4);         // length

                    put_byte(ctx->pb, 0x00);           // substream ID, 00=PCI

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

                        put_byte(ctx->pb, 0x00);

                    put_be32(ctx->pb, PRIVATE_STREAM_2);

                    put_be16(ctx->pb, 0x03fa);         // length

                    put_byte(ctx->pb, 0x01);           // substream ID, 01=DSI

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

                        put_byte(ctx->pb, 0x00);

                    memset(buffer, 0, 128);

                    buf_ptr = buffer;

                    s->packet_number++;

                    stream->align_iframe = 0;

                    scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet

                    size = put_pack_header(ctx, buf_ptr, scr);

                    s->last_scr= scr;

                    buf_ptr += size;

                    /* GOP Start */

                } else if (stream->bytes_to_iframe < PES_bytes_to_fill) {

                    pad_packet_bytes = PES_bytes_to_fill - stream->bytes_to_iframe;

                }

            }

        } else {

            if ((s->packet_number % s->system_header_freq) == 0) {

                size = put_system_header(ctx, buf_ptr, 0);

                buf_ptr += size;

            }

        }

    }

    size = buf_ptr - buffer;

    put_buffer(ctx->pb, buffer, size);

    packet_size = s->packet_size - size;

    if (s->is_vcd && id == AUDIO_ID)

        /* The VCD standard demands that 20 zero bytes follow

           each audio pack (see standard p. IV-8).*/

        zero_trail_bytes += 20;

    if ((s->is_vcd && stream->packet_number==0)

        || (s->is_svcd && s->packet_number==0)) {

        /* for VCD the first pack of each stream contains only the pack header,

           the system header and lots of padding (see VCD standard p. IV-6).

           In the case of an audio pack, 20 zero bytes are also added at

           the end.*/

        /* For SVCD we fill the very first pack to increase compatibility with

           some DVD players. Not mandated by the standard.*/

        if (s->is_svcd)

            general_pack = 1;    /* the system header refers to both streams and no stream data*/

        pad_packet_bytes = packet_size - zero_trail_bytes;

    }

    packet_size -= pad_packet_bytes + zero_trail_bytes;

    if (packet_size > 0) {

        /* packet header size */

        packet_size -= 6;

        /* packet header */

        if (s->is_mpeg2) {

            header_len = 3;

            if (stream->packet_number==0)

                header_len += 3; /* PES extension */

            header_len += 1; /* obligatory stuffing byte */

        } else {

            header_len = 0;

        }

        if (pts != AV_NOPTS_VALUE) {

            if (dts != pts)

                header_len += 5 + 5;

            else

                header_len += 5;

        } else {

            if (!s->is_mpeg2)

                header_len++;

        }

        payload_size = packet_size - header_len;

        if (id < 0xc0) {

            startcode = PRIVATE_STREAM_1;

            payload_size -= 1;

            if (id >= 0x40) {

                payload_size -= 3;

                if (id >= 0xa0)

                    payload_size -= 3;

            }

        } else {

            startcode = 0x100 + id;

        }

        stuffing_size = payload_size - av_fifo_size(stream->fifo);

        // first byte does not fit -> reset pts/dts + stuffing

        if(payload_size <= trailer_size && pts != AV_NOPTS_VALUE){

            int timestamp_len=0;

            if(dts != pts)

                timestamp_len += 5;

            if(pts != AV_NOPTS_VALUE)

                timestamp_len += s->is_mpeg2 ? 5 : 4;

            pts=dts= AV_NOPTS_VALUE;

            header_len -= timestamp_len;

            if (s->is_dvd && stream->align_iframe) {

                pad_packet_bytes += timestamp_len;

                packet_size  -= timestamp_len;

            } else {

                payload_size += timestamp_len;

            }

            stuffing_size += timestamp_len;

            if(payload_size > trailer_size)

                stuffing_size += payload_size - trailer_size;

        }

        if (pad_packet_bytes > 0 && pad_packet_bytes <= 7) { // can't use padding, so use stuffing

            packet_size += pad_packet_bytes;

            payload_size += pad_packet_bytes; // undo the previous adjustment

            if (stuffing_size < 0) {

                stuffing_size  = pad_packet_bytes;

            } else {

                stuffing_size += pad_packet_bytes;

            }

            pad_packet_bytes = 0;

        }

        if (stuffing_size < 0)

            stuffing_size = 0;

        if (stuffing_size > 16) {    /*<=16 for MPEG-1, <=32 for MPEG-2*/

            pad_packet_bytes += stuffing_size;

            packet_size      -= stuffing_size;

            payload_size     -= stuffing_size;

            stuffing_size = 0;

        }

        nb_frames= get_nb_frames(ctx, stream, payload_size - stuffing_size);

        put_be32(ctx->pb, startcode);

        put_be16(ctx->pb, packet_size);

        if (!s->is_mpeg2)

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

                put_byte(ctx->pb, 0xff);

        if (s->is_mpeg2) {

            put_byte(ctx->pb, 0x80); /* mpeg2 id */

            pes_flags=0;

            if (pts != AV_NOPTS_VALUE) {

                pes_flags |= 0x80;

                if (dts != pts)

                    pes_flags |= 0x40;

            }

            /* Both the MPEG-2 and the SVCD standards demand that the

               P-STD_buffer_size field be included in the first packet of

               every stream. (see SVCD standard p. 26 V.2.3.1 and V.2.3.2

               and MPEG-2 standard 2.7.7) */

            if (stream->packet_number == 0)

                pes_flags |= 0x01;

            put_byte(ctx->pb, pes_flags); /* flags */

            put_byte(ctx->pb, header_len - 3 + stuffing_size);

            if (pes_flags & 0x80)  /*write pts*/

                put_timestamp(ctx->pb, (pes_flags & 0x40) ? 0x03 : 0x02, pts);

            if (pes_flags & 0x40)  /*write dts*/

                put_timestamp(ctx->pb, 0x01, dts);

            if (pes_flags & 0x01) {  /*write pes extension*/

                put_byte(ctx->pb, 0x10); /* flags */

                /* P-STD buffer info */

                if (id == AUDIO_ID)

                    put_be16(ctx->pb, 0x4000 | stream->max_buffer_size/ 128);

                else

                    put_be16(ctx->pb, 0x6000 | stream->max_buffer_size/1024);

            }

        } else {

            if (pts != AV_NOPTS_VALUE) {

                if (dts != pts) {

                    put_timestamp(ctx->pb, 0x03, pts);

                    put_timestamp(ctx->pb, 0x01, dts);

                } else {

                    put_timestamp(ctx->pb, 0x02, pts);

                }

            } else {

                put_byte(ctx->pb, 0x0f);

            }

        }

        if (s->is_mpeg2) {

            /* special stuffing byte that is always written

               to prevent accidental generation of start codes. */

            put_byte(ctx->pb, 0xff);

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

                put_byte(ctx->pb, 0xff);

        }

        if (startcode == PRIVATE_STREAM_1) {

            put_byte(ctx->pb, id);

            if (id >= 0xa0) {

                /* LPCM (XXX: check nb_frames) */

                put_byte(ctx->pb, 7);

                put_be16(ctx->pb, 4); /* skip 3 header bytes */

                put_byte(ctx->pb, stream->lpcm_header[0]);

                put_byte(ctx->pb, stream->lpcm_header[1]);

                put_byte(ctx->pb, stream->lpcm_header[2]);

            } else if (id >= 0x40) {

                /* AC-3 */

                put_byte(ctx->pb, nb_frames);

                put_be16(ctx->pb, trailer_size+1);

            }

        }

        /* output data */

        assert(payload_size - stuffing_size <= av_fifo_size(stream->fifo));

        av_fifo_generic_read(stream->fifo, ctx->pb, payload_size - stuffing_size, &put_buffer);

        stream->bytes_to_iframe -= payload_size - stuffing_size;

    }else{

        payload_size=

        stuffing_size= 0;

    }

    if (pad_packet_bytes > 0)

        put_padding_packet(ctx,ctx->pb, pad_packet_bytes);

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

        put_byte(ctx->pb, 0x00);

    put_flush_packet(ctx->pb);

    s->packet_number++;

    /* only increase the stream packet number if this pack actually contains

       something that is specific to this stream! I.e. a dedicated header

       or some data.*/

    if (!general_pack)

        stream->packet_number++;

    return payload_size - stuffing_size;

}