Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Sat, 16 Feb 2013 20:14:00 +0000 (21:14 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 16 Feb 2013 22:30:09 +0000 (23:30 +0100)
* qatar/master:
  h264: deMpegEncContextize

Conflicts:
libavcodec/dxva2_h264.c
libavcodec/h264.c
libavcodec/h264.h
libavcodec/h264_cabac.c
libavcodec/h264_cavlc.c
libavcodec/h264_loopfilter.c
libavcodec/h264_mb_template.c
libavcodec/h264_parser.c
libavcodec/h264_ps.c
libavcodec/h264_refs.c
libavcodec/h264_sei.c
libavcodec/svq3.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
35 files changed:
1  2 
libavcodec/crystalhd.c
libavcodec/dxva2.c
libavcodec/dxva2_h264.c
libavcodec/dxva2_internal.h
libavcodec/dxva2_mpeg2.c
libavcodec/dxva2_vc1.c
libavcodec/h264.c
libavcodec/h264.h
libavcodec/h264_cabac.c
libavcodec/h264_cavlc.c
libavcodec/h264_direct.c
libavcodec/h264_loopfilter.c
libavcodec/h264_mb_template.c
libavcodec/h264_mc_template.c
libavcodec/h264_mvpred.h
libavcodec/h264_parser.c
libavcodec/h264_ps.c
libavcodec/h264_refs.c
libavcodec/h264_sei.c
libavcodec/h264pred.c
libavcodec/mpegvideo.h
libavcodec/svq3.c
libavcodec/vaapi.c
libavcodec/vaapi_h264.c
libavcodec/vaapi_internal.h
libavcodec/vaapi_mpeg2.c
libavcodec/vaapi_mpeg4.c
libavcodec/vaapi_vc1.c
libavcodec/vda_h264.c
libavcodec/vdpau.c
libavcodec/vdpau_h264.c
libavcodec/vdpau_internal.h
libavcodec/vdpau_mpeg12.c
libavcodec/vdpau_mpeg4.c
libavcodec/vdpau_vc1.c

index 95f1fb6,0000000..e2596a2
mode 100644,000000..100644
--- /dev/null
@@@ -1,1226 -1,0 +1,1226 @@@
-                            h->s.picture_structure);
-                     pic_type = h->s.picture_structure;
 +/*
 + * - CrystalHD decoder module -
 + *
 + * Copyright(C) 2010,2011 Philip Langdale <ffmpeg.philipl@overt.org>
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
 +/*
 + * - Principles of Operation -
 + *
 + * The CrystalHD decoder operates at the bitstream level - which is an even
 + * higher level than the decoding hardware you typically see in modern GPUs.
 + * This means it has a very simple interface, in principle. You feed demuxed
 + * packets in one end and get decoded picture (fields/frames) out the other.
 + *
 + * Of course, nothing is ever that simple. Due, at the very least, to b-frame
 + * dependencies in the supported formats, the hardware has a delay between
 + * when a packet goes in, and when a picture comes out. Furthermore, this delay
 + * is not just a function of time, but also one of the dependency on additional
 + * frames being fed into the decoder to satisfy the b-frame dependencies.
 + *
 + * As such, a pipeline will build up that is roughly equivalent to the required
 + * DPB for the file being played. If that was all it took, things would still
 + * be simple - so, of course, it isn't.
 + *
 + * The hardware has a way of indicating that a picture is ready to be copied out,
 + * but this is unreliable - and sometimes the attempt will still fail so, based
 + * on testing, the code will wait until 3 pictures are ready before starting
 + * to copy out - and this has the effect of extending the pipeline.
 + *
 + * Finally, while it is tempting to say that once the decoder starts outputting
 + * frames, the software should never fail to return a frame from a decode(),
 + * this is a hard assertion to make, because the stream may switch between
 + * differently encoded content (number of b-frames, interlacing, etc) which
 + * might require a longer pipeline than before. If that happened, you could
 + * deadlock trying to retrieve a frame that can't be decoded without feeding
 + * in additional packets.
 + *
 + * As such, the code will return in the event that a picture cannot be copied
 + * out, leading to an increase in the length of the pipeline. This in turn,
 + * means we have to be sensitive to the time it takes to decode a picture;
 + * We do not want to give up just because the hardware needed a little more
 + * time to prepare the picture! For this reason, there are delays included
 + * in the decode() path that ensure that, under normal conditions, the hardware
 + * will only fail to return a frame if it really needs additional packets to
 + * complete the decoding.
 + *
 + * Finally, to be explicit, we do not want the pipeline to grow without bound
 + * for two reasons: 1) The hardware can only buffer a finite number of packets,
 + * and 2) The client application may not be able to cope with arbitrarily long
 + * delays in the video path relative to the audio path. For example. MPlayer
 + * can only handle a 20 picture delay (although this is arbitrary, and needs
 + * to be extended to fully support the CrystalHD where the delay could be up
 + * to 32 pictures - consider PAFF H.264 content with 16 b-frames).
 + */
 +
 +/*****************************************************************************
 + * Includes
 + ****************************************************************************/
 +
 +#define _XOPEN_SOURCE 600
 +#include <inttypes.h>
 +#include <stdio.h>
 +#include <stdlib.h>
 +#include <unistd.h>
 +
 +#include <libcrystalhd/bc_dts_types.h>
 +#include <libcrystalhd/bc_dts_defs.h>
 +#include <libcrystalhd/libcrystalhd_if.h>
 +
 +#include "avcodec.h"
 +#include "h264.h"
 +#include "internal.h"
 +#include "libavutil/imgutils.h"
 +#include "libavutil/intreadwrite.h"
 +#include "libavutil/opt.h"
 +
 +/** Timeout parameter passed to DtsProcOutput() in us */
 +#define OUTPUT_PROC_TIMEOUT 50
 +/** Step between fake timestamps passed to hardware in units of 100ns */
 +#define TIMESTAMP_UNIT 100000
 +/** Initial value in us of the wait in decode() */
 +#define BASE_WAIT 10000
 +/** Increment in us to adjust wait in decode() */
 +#define WAIT_UNIT 1000
 +
 +
 +/*****************************************************************************
 + * Module private data
 + ****************************************************************************/
 +
 +typedef enum {
 +    RET_ERROR           = -1,
 +    RET_OK              = 0,
 +    RET_COPY_AGAIN      = 1,
 +    RET_SKIP_NEXT_COPY  = 2,
 +    RET_COPY_NEXT_FIELD = 3,
 +} CopyRet;
 +
 +typedef struct OpaqueList {
 +    struct OpaqueList *next;
 +    uint64_t fake_timestamp;
 +    uint64_t reordered_opaque;
 +    uint8_t pic_type;
 +} OpaqueList;
 +
 +typedef struct {
 +    AVClass *av_class;
 +    AVCodecContext *avctx;
 +    AVFrame pic;
 +    HANDLE dev;
 +
 +    uint8_t *orig_extradata;
 +    uint32_t orig_extradata_size;
 +
 +    AVBitStreamFilterContext *bsfc;
 +    AVCodecParserContext *parser;
 +
 +    uint8_t is_70012;
 +    uint8_t *sps_pps_buf;
 +    uint32_t sps_pps_size;
 +    uint8_t is_nal;
 +    uint8_t output_ready;
 +    uint8_t need_second_field;
 +    uint8_t skip_next_output;
 +    uint64_t decode_wait;
 +
 +    uint64_t last_picture;
 +
 +    OpaqueList *head;
 +    OpaqueList *tail;
 +
 +    /* Options */
 +    uint32_t sWidth;
 +    uint8_t bframe_bug;
 +} CHDContext;
 +
 +static const AVOption options[] = {
 +    { "crystalhd_downscale_width",
 +      "Turn on downscaling to the specified width",
 +      offsetof(CHDContext, sWidth),
 +      AV_OPT_TYPE_INT, {.i64 = 0}, 0, UINT32_MAX,
 +      AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, },
 +    { NULL, },
 +};
 +
 +
 +/*****************************************************************************
 + * Helper functions
 + ****************************************************************************/
 +
 +static inline BC_MEDIA_SUBTYPE id2subtype(CHDContext *priv, enum AVCodecID id)
 +{
 +    switch (id) {
 +    case AV_CODEC_ID_MPEG4:
 +        return BC_MSUBTYPE_DIVX;
 +    case AV_CODEC_ID_MSMPEG4V3:
 +        return BC_MSUBTYPE_DIVX311;
 +    case AV_CODEC_ID_MPEG2VIDEO:
 +        return BC_MSUBTYPE_MPEG2VIDEO;
 +    case AV_CODEC_ID_VC1:
 +        return BC_MSUBTYPE_VC1;
 +    case AV_CODEC_ID_WMV3:
 +        return BC_MSUBTYPE_WMV3;
 +    case AV_CODEC_ID_H264:
 +        return priv->is_nal ? BC_MSUBTYPE_AVC1 : BC_MSUBTYPE_H264;
 +    default:
 +        return BC_MSUBTYPE_INVALID;
 +    }
 +}
 +
 +static inline void print_frame_info(CHDContext *priv, BC_DTS_PROC_OUT *output)
 +{
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tYBuffSz: %u\n", output->YbuffSz);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tYBuffDoneSz: %u\n",
 +           output->YBuffDoneSz);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tUVBuffDoneSz: %u\n",
 +           output->UVBuffDoneSz);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tTimestamp: %"PRIu64"\n",
 +           output->PicInfo.timeStamp);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tPicture Number: %u\n",
 +           output->PicInfo.picture_number);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tWidth: %u\n",
 +           output->PicInfo.width);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tHeight: %u\n",
 +           output->PicInfo.height);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tChroma: 0x%03x\n",
 +           output->PicInfo.chroma_format);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tPulldown: %u\n",
 +           output->PicInfo.pulldown);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tFlags: 0x%08x\n",
 +           output->PicInfo.flags);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tFrame Rate/Res: %u\n",
 +           output->PicInfo.frame_rate);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tAspect Ratio: %u\n",
 +           output->PicInfo.aspect_ratio);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tColor Primaries: %u\n",
 +           output->PicInfo.colour_primaries);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tMetaData: %u\n",
 +           output->PicInfo.picture_meta_payload);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tSession Number: %u\n",
 +           output->PicInfo.sess_num);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tycom: %u\n",
 +           output->PicInfo.ycom);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tCustom Aspect: %u\n",
 +           output->PicInfo.custom_aspect_ratio_width_height);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tFrames to Drop: %u\n",
 +           output->PicInfo.n_drop);
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "\tH264 Valid Fields: 0x%08x\n",
 +           output->PicInfo.other.h264.valid);
 +}
 +
 +
 +/*****************************************************************************
 + * OpaqueList functions
 + ****************************************************************************/
 +
 +static uint64_t opaque_list_push(CHDContext *priv, uint64_t reordered_opaque,
 +                                 uint8_t pic_type)
 +{
 +    OpaqueList *newNode = av_mallocz(sizeof (OpaqueList));
 +    if (!newNode) {
 +        av_log(priv->avctx, AV_LOG_ERROR,
 +               "Unable to allocate new node in OpaqueList.\n");
 +        return 0;
 +    }
 +    if (!priv->head) {
 +        newNode->fake_timestamp = TIMESTAMP_UNIT;
 +        priv->head              = newNode;
 +    } else {
 +        newNode->fake_timestamp = priv->tail->fake_timestamp + TIMESTAMP_UNIT;
 +        priv->tail->next        = newNode;
 +    }
 +    priv->tail = newNode;
 +    newNode->reordered_opaque = reordered_opaque;
 +    newNode->pic_type = pic_type;
 +
 +    return newNode->fake_timestamp;
 +}
 +
 +/*
 + * The OpaqueList is built in decode order, while elements will be removed
 + * in presentation order. If frames are reordered, this means we must be
 + * able to remove elements that are not the first element.
 + *
 + * Returned node must be freed by caller.
 + */
 +static OpaqueList *opaque_list_pop(CHDContext *priv, uint64_t fake_timestamp)
 +{
 +    OpaqueList *node = priv->head;
 +
 +    if (!priv->head) {
 +        av_log(priv->avctx, AV_LOG_ERROR,
 +               "CrystalHD: Attempted to query non-existent timestamps.\n");
 +        return NULL;
 +    }
 +
 +    /*
 +     * The first element is special-cased because we have to manipulate
 +     * the head pointer rather than the previous element in the list.
 +     */
 +    if (priv->head->fake_timestamp == fake_timestamp) {
 +        priv->head = node->next;
 +
 +        if (!priv->head->next)
 +            priv->tail = priv->head;
 +
 +        node->next = NULL;
 +        return node;
 +    }
 +
 +    /*
 +     * The list is processed at arm's length so that we have the
 +     * previous element available to rewrite its next pointer.
 +     */
 +    while (node->next) {
 +        OpaqueList *current = node->next;
 +        if (current->fake_timestamp == fake_timestamp) {
 +            node->next = current->next;
 +
 +            if (!node->next)
 +               priv->tail = node;
 +
 +            current->next = NULL;
 +            return current;
 +        } else {
 +            node = current;
 +        }
 +    }
 +
 +    av_log(priv->avctx, AV_LOG_VERBOSE,
 +           "CrystalHD: Couldn't match fake_timestamp.\n");
 +    return NULL;
 +}
 +
 +
 +/*****************************************************************************
 + * Video decoder API function definitions
 + ****************************************************************************/
 +
 +static void flush(AVCodecContext *avctx)
 +{
 +    CHDContext *priv = avctx->priv_data;
 +
 +    avctx->has_b_frames     = 0;
 +    priv->last_picture      = -1;
 +    priv->output_ready      = 0;
 +    priv->need_second_field = 0;
 +    priv->skip_next_output  = 0;
 +    priv->decode_wait       = BASE_WAIT;
 +
 +    if (priv->pic.data[0])
 +        avctx->release_buffer(avctx, &priv->pic);
 +
 +    /* Flush mode 4 flushes all software and hardware buffers. */
 +    DtsFlushInput(priv->dev, 4);
 +}
 +
 +
 +static av_cold int uninit(AVCodecContext *avctx)
 +{
 +    CHDContext *priv = avctx->priv_data;
 +    HANDLE device;
 +
 +    device = priv->dev;
 +    DtsStopDecoder(device);
 +    DtsCloseDecoder(device);
 +    DtsDeviceClose(device);
 +
 +    /*
 +     * Restore original extradata, so that if the decoder is
 +     * reinitialised, the bitstream detection and filtering
 +     * will work as expected.
 +     */
 +    if (priv->orig_extradata) {
 +        av_free(avctx->extradata);
 +        avctx->extradata = priv->orig_extradata;
 +        avctx->extradata_size = priv->orig_extradata_size;
 +        priv->orig_extradata = NULL;
 +        priv->orig_extradata_size = 0;
 +    }
 +
 +    av_parser_close(priv->parser);
 +    if (priv->bsfc) {
 +        av_bitstream_filter_close(priv->bsfc);
 +    }
 +
 +    av_free(priv->sps_pps_buf);
 +
 +    if (priv->pic.data[0])
 +        avctx->release_buffer(avctx, &priv->pic);
 +
 +    if (priv->head) {
 +       OpaqueList *node = priv->head;
 +       while (node) {
 +          OpaqueList *next = node->next;
 +          av_free(node);
 +          node = next;
 +       }
 +    }
 +
 +    return 0;
 +}
 +
 +
 +static av_cold int init(AVCodecContext *avctx)
 +{
 +    CHDContext* priv;
 +    BC_STATUS ret;
 +    BC_INFO_CRYSTAL version;
 +    BC_INPUT_FORMAT format = {
 +        .FGTEnable   = FALSE,
 +        .Progressive = TRUE,
 +        .OptFlags    = 0x80000000 | vdecFrameRate59_94 | 0x40,
 +        .width       = avctx->width,
 +        .height      = avctx->height,
 +    };
 +
 +    BC_MEDIA_SUBTYPE subtype;
 +
 +    uint32_t mode = DTS_PLAYBACK_MODE |
 +                    DTS_LOAD_FILE_PLAY_FW |
 +                    DTS_SKIP_TX_CHK_CPB |
 +                    DTS_PLAYBACK_DROP_RPT_MODE |
 +                    DTS_SINGLE_THREADED_MODE |
 +                    DTS_DFLT_RESOLUTION(vdecRESOLUTION_1080p23_976);
 +
 +    av_log(avctx, AV_LOG_VERBOSE, "CrystalHD Init for %s\n",
 +           avctx->codec->name);
 +
 +    avctx->pix_fmt = AV_PIX_FMT_YUYV422;
 +
 +    /* Initialize the library */
 +    priv               = avctx->priv_data;
 +    priv->avctx        = avctx;
 +    priv->is_nal       = avctx->extradata_size > 0 && *(avctx->extradata) == 1;
 +    priv->last_picture = -1;
 +    priv->decode_wait  = BASE_WAIT;
 +
 +    subtype = id2subtype(priv, avctx->codec->id);
 +    switch (subtype) {
 +    case BC_MSUBTYPE_AVC1:
 +        {
 +            uint8_t *dummy_p;
 +            int dummy_int;
 +
 +            /* Back up the extradata so it can be restored at close time. */
 +            priv->orig_extradata = av_malloc(avctx->extradata_size);
 +            if (!priv->orig_extradata) {
 +                av_log(avctx, AV_LOG_ERROR,
 +                       "Failed to allocate copy of extradata\n");
 +                return AVERROR(ENOMEM);
 +            }
 +            priv->orig_extradata_size = avctx->extradata_size;
 +            memcpy(priv->orig_extradata, avctx->extradata, avctx->extradata_size);
 +
 +            priv->bsfc = av_bitstream_filter_init("h264_mp4toannexb");
 +            if (!priv->bsfc) {
 +                av_log(avctx, AV_LOG_ERROR,
 +                       "Cannot open the h264_mp4toannexb BSF!\n");
 +                return AVERROR_BSF_NOT_FOUND;
 +            }
 +            av_bitstream_filter_filter(priv->bsfc, avctx, NULL, &dummy_p,
 +                                       &dummy_int, NULL, 0, 0);
 +        }
 +        subtype = BC_MSUBTYPE_H264;
 +        // Fall-through
 +    case BC_MSUBTYPE_H264:
 +        format.startCodeSz = 4;
 +        // Fall-through
 +    case BC_MSUBTYPE_VC1:
 +    case BC_MSUBTYPE_WVC1:
 +    case BC_MSUBTYPE_WMV3:
 +    case BC_MSUBTYPE_WMVA:
 +    case BC_MSUBTYPE_MPEG2VIDEO:
 +    case BC_MSUBTYPE_DIVX:
 +    case BC_MSUBTYPE_DIVX311:
 +        format.pMetaData  = avctx->extradata;
 +        format.metaDataSz = avctx->extradata_size;
 +        break;
 +    default:
 +        av_log(avctx, AV_LOG_ERROR, "CrystalHD: Unknown codec name\n");
 +        return AVERROR(EINVAL);
 +    }
 +    format.mSubtype = subtype;
 +
 +    if (priv->sWidth) {
 +        format.bEnableScaling = 1;
 +        format.ScalingParams.sWidth = priv->sWidth;
 +    }
 +
 +    /* Get a decoder instance */
 +    av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: starting up\n");
 +    // Initialize the Link and Decoder devices
 +    ret = DtsDeviceOpen(&priv->dev, mode);
 +    if (ret != BC_STS_SUCCESS) {
 +        av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: DtsDeviceOpen failed\n");
 +        goto fail;
 +    }
 +
 +    ret = DtsCrystalHDVersion(priv->dev, &version);
 +    if (ret != BC_STS_SUCCESS) {
 +        av_log(avctx, AV_LOG_VERBOSE,
 +               "CrystalHD: DtsCrystalHDVersion failed\n");
 +        goto fail;
 +    }
 +    priv->is_70012 = version.device == 0;
 +
 +    if (priv->is_70012 &&
 +        (subtype == BC_MSUBTYPE_DIVX || subtype == BC_MSUBTYPE_DIVX311)) {
 +        av_log(avctx, AV_LOG_VERBOSE,
 +               "CrystalHD: BCM70012 doesn't support MPEG4-ASP/DivX/Xvid\n");
 +        goto fail;
 +    }
 +
 +    ret = DtsSetInputFormat(priv->dev, &format);
 +    if (ret != BC_STS_SUCCESS) {
 +        av_log(avctx, AV_LOG_ERROR, "CrystalHD: SetInputFormat failed\n");
 +        goto fail;
 +    }
 +
 +    ret = DtsOpenDecoder(priv->dev, BC_STREAM_TYPE_ES);
 +    if (ret != BC_STS_SUCCESS) {
 +        av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsOpenDecoder failed\n");
 +        goto fail;
 +    }
 +
 +    ret = DtsSetColorSpace(priv->dev, OUTPUT_MODE422_YUY2);
 +    if (ret != BC_STS_SUCCESS) {
 +        av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsSetColorSpace failed\n");
 +        goto fail;
 +    }
 +    ret = DtsStartDecoder(priv->dev);
 +    if (ret != BC_STS_SUCCESS) {
 +        av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsStartDecoder failed\n");
 +        goto fail;
 +    }
 +    ret = DtsStartCapture(priv->dev);
 +    if (ret != BC_STS_SUCCESS) {
 +        av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsStartCapture failed\n");
 +        goto fail;
 +    }
 +
 +    if (avctx->codec->id == AV_CODEC_ID_H264) {
 +        priv->parser = av_parser_init(avctx->codec->id);
 +        if (!priv->parser)
 +            av_log(avctx, AV_LOG_WARNING,
 +                   "Cannot open the h.264 parser! Interlaced h.264 content "
 +                   "will not be detected reliably.\n");
 +        priv->parser->flags = PARSER_FLAG_COMPLETE_FRAMES;
 +    }
 +    av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Init complete.\n");
 +
 +    return 0;
 +
 + fail:
 +    uninit(avctx);
 +    return -1;
 +}
 +
 +
 +static inline CopyRet copy_frame(AVCodecContext *avctx,
 +                                 BC_DTS_PROC_OUT *output,
 +                                 void *data, int *got_frame)
 +{
 +    BC_STATUS ret;
 +    BC_DTS_STATUS decoder_status = { 0, };
 +    uint8_t trust_interlaced;
 +    uint8_t interlaced;
 +
 +    CHDContext *priv = avctx->priv_data;
 +    int64_t pkt_pts  = AV_NOPTS_VALUE;
 +    uint8_t pic_type = 0;
 +
 +    uint8_t bottom_field = (output->PicInfo.flags & VDEC_FLAG_BOTTOMFIELD) ==
 +                           VDEC_FLAG_BOTTOMFIELD;
 +    uint8_t bottom_first = !!(output->PicInfo.flags & VDEC_FLAG_BOTTOM_FIRST);
 +
 +    int width    = output->PicInfo.width;
 +    int height   = output->PicInfo.height;
 +    int bwidth;
 +    uint8_t *src = output->Ybuff;
 +    int sStride;
 +    uint8_t *dst;
 +    int dStride;
 +
 +    if (output->PicInfo.timeStamp != 0) {
 +        OpaqueList *node = opaque_list_pop(priv, output->PicInfo.timeStamp);
 +        if (node) {
 +            pkt_pts = node->reordered_opaque;
 +            pic_type = node->pic_type;
 +            av_free(node);
 +        } else {
 +            /*
 +             * We will encounter a situation where a timestamp cannot be
 +             * popped if a second field is being returned. In this case,
 +             * each field has the same timestamp and the first one will
 +             * cause it to be popped. To keep subsequent calculations
 +             * simple, pic_type should be set a FIELD value - doesn't
 +             * matter which, but I chose BOTTOM.
 +             */
 +            pic_type = PICT_BOTTOM_FIELD;
 +        }
 +        av_log(avctx, AV_LOG_VERBOSE, "output \"pts\": %"PRIu64"\n",
 +               output->PicInfo.timeStamp);
 +        av_log(avctx, AV_LOG_VERBOSE, "output picture type %d\n",
 +               pic_type);
 +    }
 +
 +    ret = DtsGetDriverStatus(priv->dev, &decoder_status);
 +    if (ret != BC_STS_SUCCESS) {
 +        av_log(avctx, AV_LOG_ERROR,
 +               "CrystalHD: GetDriverStatus failed: %u\n", ret);
 +       return RET_ERROR;
 +    }
 +
 +    /*
 +     * For most content, we can trust the interlaced flag returned
 +     * by the hardware, but sometimes we can't. These are the
 +     * conditions under which we can trust the flag:
 +     *
 +     * 1) It's not h.264 content
 +     * 2) The UNKNOWN_SRC flag is not set
 +     * 3) We know we're expecting a second field
 +     * 4) The hardware reports this picture and the next picture
 +     *    have the same picture number.
 +     *
 +     * Note that there can still be interlaced content that will
 +     * fail this check, if the hardware hasn't decoded the next
 +     * picture or if there is a corruption in the stream. (In either
 +     * case a 0 will be returned for the next picture number)
 +     */
 +    trust_interlaced = avctx->codec->id != AV_CODEC_ID_H264 ||
 +                       !(output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) ||
 +                       priv->need_second_field ||
 +                       (decoder_status.picNumFlags & ~0x40000000) ==
 +                       output->PicInfo.picture_number;
 +
 +    /*
 +     * If we got a false negative for trust_interlaced on the first field,
 +     * we will realise our mistake here when we see that the picture number is that
 +     * of the previous picture. We cannot recover the frame and should discard the
 +     * second field to keep the correct number of output frames.
 +     */
 +    if (output->PicInfo.picture_number == priv->last_picture && !priv->need_second_field) {
 +        av_log(avctx, AV_LOG_WARNING,
 +               "Incorrectly guessed progressive frame. Discarding second field\n");
 +        /* Returning without providing a picture. */
 +        return RET_OK;
 +    }
 +
 +    interlaced = (output->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC) &&
 +                 trust_interlaced;
 +
 +    if (!trust_interlaced && (decoder_status.picNumFlags & ~0x40000000) == 0) {
 +        av_log(avctx, AV_LOG_VERBOSE,
 +               "Next picture number unknown. Assuming progressive frame.\n");
 +    }
 +
 +    av_log(avctx, AV_LOG_VERBOSE, "Interlaced state: %d | trust_interlaced %d\n",
 +           interlaced, trust_interlaced);
 +
 +    if (priv->pic.data[0] && !priv->need_second_field)
 +        avctx->release_buffer(avctx, &priv->pic);
 +
 +    priv->need_second_field = interlaced && !priv->need_second_field;
 +
 +    priv->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
 +                             FF_BUFFER_HINTS_REUSABLE;
 +    if (!priv->pic.data[0]) {
 +        if (ff_get_buffer(avctx, &priv->pic) < 0) {
 +            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 +            return RET_ERROR;
 +        }
 +    }
 +
 +    bwidth = av_image_get_linesize(avctx->pix_fmt, width, 0);
 +    if (priv->is_70012) {
 +        int pStride;
 +
 +        if (width <= 720)
 +            pStride = 720;
 +        else if (width <= 1280)
 +            pStride = 1280;
 +        else pStride = 1920;
 +        sStride = av_image_get_linesize(avctx->pix_fmt, pStride, 0);
 +    } else {
 +        sStride = bwidth;
 +    }
 +
 +    dStride = priv->pic.linesize[0];
 +    dst     = priv->pic.data[0];
 +
 +    av_log(priv->avctx, AV_LOG_VERBOSE, "CrystalHD: Copying out frame\n");
 +
 +    if (interlaced) {
 +        int dY = 0;
 +        int sY = 0;
 +
 +        height /= 2;
 +        if (bottom_field) {
 +            av_log(priv->avctx, AV_LOG_VERBOSE, "Interlaced: bottom field\n");
 +            dY = 1;
 +        } else {
 +            av_log(priv->avctx, AV_LOG_VERBOSE, "Interlaced: top field\n");
 +            dY = 0;
 +        }
 +
 +        for (sY = 0; sY < height; dY++, sY++) {
 +            memcpy(&(dst[dY * dStride]), &(src[sY * sStride]), bwidth);
 +            dY++;
 +        }
 +    } else {
 +        av_image_copy_plane(dst, dStride, src, sStride, bwidth, height);
 +    }
 +
 +    priv->pic.interlaced_frame = interlaced;
 +    if (interlaced)
 +        priv->pic.top_field_first = !bottom_first;
 +
 +    priv->pic.pkt_pts = pkt_pts;
 +
 +    if (!priv->need_second_field) {
 +        *got_frame       = 1;
 +        *(AVFrame *)data = priv->pic;
 +    }
 +
 +    /*
 +     * Two types of PAFF content have been observed. One form causes the
 +     * hardware to return a field pair and the other individual fields,
 +     * even though the input is always individual fields. We must skip
 +     * copying on the next decode() call to maintain pipeline length in
 +     * the first case.
 +     */
 +    if (!interlaced && (output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) &&
 +        (pic_type == PICT_TOP_FIELD || pic_type == PICT_BOTTOM_FIELD)) {
 +        av_log(priv->avctx, AV_LOG_VERBOSE, "Fieldpair from two packets.\n");
 +        return RET_SKIP_NEXT_COPY;
 +    }
 +
 +    /*
 +     * The logic here is purely based on empirical testing with samples.
 +     * If we need a second field, it could come from a second input packet,
 +     * or it could come from the same field-pair input packet at the current
 +     * field. In the first case, we should return and wait for the next time
 +     * round to get the second field, while in the second case, we should
 +     * ask the decoder for it immediately.
 +     *
 +     * Testing has shown that we are dealing with the fieldpair -> two fields
 +     * case if the VDEC_FLAG_UNKNOWN_SRC is not set or if the input picture
 +     * type was PICT_FRAME (in this second case, the flag might still be set)
 +     */
 +    return priv->need_second_field &&
 +           (!(output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) ||
 +            pic_type == PICT_FRAME) ?
 +           RET_COPY_NEXT_FIELD : RET_OK;
 +}
 +
 +
 +static inline CopyRet receive_frame(AVCodecContext *avctx,
 +                                    void *data, int *got_frame)
 +{
 +    BC_STATUS ret;
 +    BC_DTS_PROC_OUT output = {
 +        .PicInfo.width  = avctx->width,
 +        .PicInfo.height = avctx->height,
 +    };
 +    CHDContext *priv = avctx->priv_data;
 +    HANDLE dev       = priv->dev;
 +
 +    *got_frame = 0;
 +
 +    // Request decoded data from the driver
 +    ret = DtsProcOutputNoCopy(dev, OUTPUT_PROC_TIMEOUT, &output);
 +    if (ret == BC_STS_FMT_CHANGE) {
 +        av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Initial format change\n");
 +        avctx->width  = output.PicInfo.width;
 +        avctx->height = output.PicInfo.height;
 +        switch ( output.PicInfo.aspect_ratio ) {
 +        case vdecAspectRatioSquare:
 +            avctx->sample_aspect_ratio = (AVRational) {  1,  1};
 +            break;
 +        case vdecAspectRatio12_11:
 +            avctx->sample_aspect_ratio = (AVRational) { 12, 11};
 +            break;
 +        case vdecAspectRatio10_11:
 +            avctx->sample_aspect_ratio = (AVRational) { 10, 11};
 +            break;
 +        case vdecAspectRatio16_11:
 +            avctx->sample_aspect_ratio = (AVRational) { 16, 11};
 +            break;
 +        case vdecAspectRatio40_33:
 +            avctx->sample_aspect_ratio = (AVRational) { 40, 33};
 +            break;
 +        case vdecAspectRatio24_11:
 +            avctx->sample_aspect_ratio = (AVRational) { 24, 11};
 +            break;
 +        case vdecAspectRatio20_11:
 +            avctx->sample_aspect_ratio = (AVRational) { 20, 11};
 +            break;
 +        case vdecAspectRatio32_11:
 +            avctx->sample_aspect_ratio = (AVRational) { 32, 11};
 +            break;
 +        case vdecAspectRatio80_33:
 +            avctx->sample_aspect_ratio = (AVRational) { 80, 33};
 +            break;
 +        case vdecAspectRatio18_11:
 +            avctx->sample_aspect_ratio = (AVRational) { 18, 11};
 +            break;
 +        case vdecAspectRatio15_11:
 +            avctx->sample_aspect_ratio = (AVRational) { 15, 11};
 +            break;
 +        case vdecAspectRatio64_33:
 +            avctx->sample_aspect_ratio = (AVRational) { 64, 33};
 +            break;
 +        case vdecAspectRatio160_99:
 +            avctx->sample_aspect_ratio = (AVRational) {160, 99};
 +            break;
 +        case vdecAspectRatio4_3:
 +            avctx->sample_aspect_ratio = (AVRational) {  4,  3};
 +            break;
 +        case vdecAspectRatio16_9:
 +            avctx->sample_aspect_ratio = (AVRational) { 16,  9};
 +            break;
 +        case vdecAspectRatio221_1:
 +            avctx->sample_aspect_ratio = (AVRational) {221,  1};
 +            break;
 +        }
 +        return RET_COPY_AGAIN;
 +    } else if (ret == BC_STS_SUCCESS) {
 +        int copy_ret = -1;
 +        if (output.PoutFlags & BC_POUT_FLAGS_PIB_VALID) {
 +            if (priv->last_picture == -1) {
 +                /*
 +                 * Init to one less, so that the incrementing code doesn't
 +                 * need to be special-cased.
 +                 */
 +                priv->last_picture = output.PicInfo.picture_number - 1;
 +            }
 +
 +            if (avctx->codec->id == AV_CODEC_ID_MPEG4 &&
 +                output.PicInfo.timeStamp == 0 && priv->bframe_bug) {
 +                av_log(avctx, AV_LOG_VERBOSE,
 +                       "CrystalHD: Not returning packed frame twice.\n");
 +                priv->last_picture++;
 +                DtsReleaseOutputBuffs(dev, NULL, FALSE);
 +                return RET_COPY_AGAIN;
 +            }
 +
 +            print_frame_info(priv, &output);
 +
 +            if (priv->last_picture + 1 < output.PicInfo.picture_number) {
 +                av_log(avctx, AV_LOG_WARNING,
 +                       "CrystalHD: Picture Number discontinuity\n");
 +                /*
 +                 * Have we lost frames? If so, we need to shrink the
 +                 * pipeline length appropriately.
 +                 *
 +                 * XXX: I have no idea what the semantics of this situation
 +                 * are so I don't even know if we've lost frames or which
 +                 * ones.
 +                 *
 +                 * In any case, only warn the first time.
 +                 */
 +               priv->last_picture = output.PicInfo.picture_number - 1;
 +            }
 +
 +            copy_ret = copy_frame(avctx, &output, data, got_frame);
 +            if (*got_frame > 0) {
 +                avctx->has_b_frames--;
 +                priv->last_picture++;
 +                av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Pipeline length: %u\n",
 +                       avctx->has_b_frames);
 +            }
 +        } else {
 +            /*
 +             * An invalid frame has been consumed.
 +             */
 +            av_log(avctx, AV_LOG_ERROR, "CrystalHD: ProcOutput succeeded with "
 +                                        "invalid PIB\n");
 +            avctx->has_b_frames--;
 +            copy_ret = RET_OK;
 +        }
 +        DtsReleaseOutputBuffs(dev, NULL, FALSE);
 +
 +        return copy_ret;
 +    } else if (ret == BC_STS_BUSY) {
 +        return RET_COPY_AGAIN;
 +    } else {
 +        av_log(avctx, AV_LOG_ERROR, "CrystalHD: ProcOutput failed %d\n", ret);
 +        return RET_ERROR;
 +    }
 +}
 +
 +
 +static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 +{
 +    BC_STATUS ret;
 +    BC_DTS_STATUS decoder_status = { 0, };
 +    CopyRet rec_ret;
 +    CHDContext *priv   = avctx->priv_data;
 +    HANDLE dev         = priv->dev;
 +    uint8_t *in_data   = avpkt->data;
 +    int len            = avpkt->size;
 +    int free_data      = 0;
 +    uint8_t pic_type   = 0;
 +
 +    av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: decode_frame\n");
 +
 +    if (avpkt->size == 7 && !priv->bframe_bug) {
 +        /*
 +         * The use of a drop frame triggers the bug
 +         */
 +        av_log(avctx, AV_LOG_INFO,
 +               "CrystalHD: Enabling work-around for packed b-frame bug\n");
 +        priv->bframe_bug = 1;
 +    } else if (avpkt->size == 8 && priv->bframe_bug) {
 +        /*
 +         * Delay frames don't trigger the bug
 +         */
 +        av_log(avctx, AV_LOG_INFO,
 +               "CrystalHD: Disabling work-around for packed b-frame bug\n");
 +        priv->bframe_bug = 0;
 +    }
 +
 +    if (len) {
 +        int32_t tx_free = (int32_t)DtsTxFreeSize(dev);
 +
 +        if (priv->parser) {
 +            int ret = 0;
 +
 +            if (priv->bsfc) {
 +                ret = av_bitstream_filter_filter(priv->bsfc, avctx, NULL,
 +                                                 &in_data, &len,
 +                                                 avpkt->data, len, 0);
 +            }
 +            free_data = ret > 0;
 +
 +            if (ret >= 0) {
 +                uint8_t *pout;
 +                int psize;
 +                int index;
 +                H264Context *h = priv->parser->priv_data;
 +
 +                index = av_parser_parse2(priv->parser, avctx, &pout, &psize,
 +                                         in_data, len, avctx->pkt->pts,
 +                                         avctx->pkt->dts, 0);
 +                if (index < 0) {
 +                    av_log(avctx, AV_LOG_WARNING,
 +                           "CrystalHD: Failed to parse h.264 packet to "
 +                           "detect interlacing.\n");
 +                } else if (index != len) {
 +                    av_log(avctx, AV_LOG_WARNING,
 +                           "CrystalHD: Failed to parse h.264 packet "
 +                           "completely. Interlaced frames may be "
 +                           "incorrectly detected.\n");
 +                } else {
 +                    av_log(avctx, AV_LOG_VERBOSE,
 +                           "CrystalHD: parser picture type %d\n",
++                           h->picture_structure);
++                    pic_type = h->picture_structure;
 +                }
 +            } else {
 +                av_log(avctx, AV_LOG_WARNING,
 +                       "CrystalHD: mp4toannexb filter failed to filter "
 +                       "packet. Interlaced frames may be incorrectly "
 +                       "detected.\n");
 +            }
 +        }
 +
 +        if (len < tx_free - 1024) {
 +            /*
 +             * Despite being notionally opaque, either libcrystalhd or
 +             * the hardware itself will mangle pts values that are too
 +             * small or too large. The docs claim it should be in units
 +             * of 100ns. Given that we're nominally dealing with a black
 +             * box on both sides, any transform we do has no guarantee of
 +             * avoiding mangling so we need to build a mapping to values
 +             * we know will not be mangled.
 +             */
 +            uint64_t pts = opaque_list_push(priv, avctx->pkt->pts, pic_type);
 +            if (!pts) {
 +                if (free_data) {
 +                    av_freep(&in_data);
 +                }
 +                return AVERROR(ENOMEM);
 +            }
 +            av_log(priv->avctx, AV_LOG_VERBOSE,
 +                   "input \"pts\": %"PRIu64"\n", pts);
 +            ret = DtsProcInput(dev, in_data, len, pts, 0);
 +            if (free_data) {
 +                av_freep(&in_data);
 +            }
 +            if (ret == BC_STS_BUSY) {
 +                av_log(avctx, AV_LOG_WARNING,
 +                       "CrystalHD: ProcInput returned busy\n");
 +                usleep(BASE_WAIT);
 +                return AVERROR(EBUSY);
 +            } else if (ret != BC_STS_SUCCESS) {
 +                av_log(avctx, AV_LOG_ERROR,
 +                       "CrystalHD: ProcInput failed: %u\n", ret);
 +                return -1;
 +            }
 +            avctx->has_b_frames++;
 +        } else {
 +            av_log(avctx, AV_LOG_WARNING, "CrystalHD: Input buffer full\n");
 +            len = 0; // We didn't consume any bytes.
 +        }
 +    } else {
 +        av_log(avctx, AV_LOG_INFO, "CrystalHD: No more input data\n");
 +    }
 +
 +    if (priv->skip_next_output) {
 +        av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Skipping next output.\n");
 +        priv->skip_next_output = 0;
 +        avctx->has_b_frames--;
 +        return len;
 +    }
 +
 +    ret = DtsGetDriverStatus(dev, &decoder_status);
 +    if (ret != BC_STS_SUCCESS) {
 +        av_log(avctx, AV_LOG_ERROR, "CrystalHD: GetDriverStatus failed\n");
 +        return -1;
 +    }
 +
 +    /*
 +     * No frames ready. Don't try to extract.
 +     *
 +     * Empirical testing shows that ReadyListCount can be a damn lie,
 +     * and ProcOut still fails when count > 0. The same testing showed
 +     * that two more iterations were needed before ProcOutput would
 +     * succeed.
 +     */
 +    if (priv->output_ready < 2) {
 +        if (decoder_status.ReadyListCount != 0)
 +            priv->output_ready++;
 +        usleep(BASE_WAIT);
 +        av_log(avctx, AV_LOG_INFO, "CrystalHD: Filling pipeline.\n");
 +        return len;
 +    } else if (decoder_status.ReadyListCount == 0) {
 +        /*
 +         * After the pipeline is established, if we encounter a lack of frames
 +         * that probably means we're not giving the hardware enough time to
 +         * decode them, so start increasing the wait time at the end of a
 +         * decode call.
 +         */
 +        usleep(BASE_WAIT);
 +        priv->decode_wait += WAIT_UNIT;
 +        av_log(avctx, AV_LOG_INFO, "CrystalHD: No frames ready. Returning\n");
 +        return len;
 +    }
 +
 +    do {
 +        rec_ret = receive_frame(avctx, data, got_frame);
 +        if (rec_ret == RET_OK && *got_frame == 0) {
 +            /*
 +             * This case is for when the encoded fields are stored
 +             * separately and we get a separate avpkt for each one. To keep
 +             * the pipeline stable, we should return nothing and wait for
 +             * the next time round to grab the second field.
 +             * H.264 PAFF is an example of this.
 +             */
 +            av_log(avctx, AV_LOG_VERBOSE, "Returning after first field.\n");
 +            avctx->has_b_frames--;
 +        } else if (rec_ret == RET_COPY_NEXT_FIELD) {
 +            /*
 +             * This case is for when the encoded fields are stored in a
 +             * single avpkt but the hardware returns then separately. Unless
 +             * we grab the second field before returning, we'll slip another
 +             * frame in the pipeline and if that happens a lot, we're sunk.
 +             * So we have to get that second field now.
 +             * Interlaced mpeg2 and vc1 are examples of this.
 +             */
 +            av_log(avctx, AV_LOG_VERBOSE, "Trying to get second field.\n");
 +            while (1) {
 +                usleep(priv->decode_wait);
 +                ret = DtsGetDriverStatus(dev, &decoder_status);
 +                if (ret == BC_STS_SUCCESS &&
 +                    decoder_status.ReadyListCount > 0) {
 +                    rec_ret = receive_frame(avctx, data, got_frame);
 +                    if ((rec_ret == RET_OK && *got_frame > 0) ||
 +                        rec_ret == RET_ERROR)
 +                        break;
 +                }
 +            }
 +            av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Got second field.\n");
 +        } else if (rec_ret == RET_SKIP_NEXT_COPY) {
 +            /*
 +             * Two input packets got turned into a field pair. Gawd.
 +             */
 +            av_log(avctx, AV_LOG_VERBOSE,
 +                   "Don't output on next decode call.\n");
 +            priv->skip_next_output = 1;
 +        }
 +        /*
 +         * If rec_ret == RET_COPY_AGAIN, that means that either we just handled
 +         * a FMT_CHANGE event and need to go around again for the actual frame,
 +         * we got a busy status and need to try again, or we're dealing with
 +         * packed b-frames, where the hardware strangely returns the packed
 +         * p-frame twice. We choose to keep the second copy as it carries the
 +         * valid pts.
 +         */
 +    } while (rec_ret == RET_COPY_AGAIN);
 +    usleep(priv->decode_wait);
 +    return len;
 +}
 +
 +
 +#if CONFIG_H264_CRYSTALHD_DECODER
 +static AVClass h264_class = {
 +    "h264_crystalhd",
 +    av_default_item_name,
 +    options,
 +    LIBAVUTIL_VERSION_INT,
 +};
 +
 +AVCodec ff_h264_crystalhd_decoder = {
 +    .name           = "h264_crystalhd",
 +    .type           = AVMEDIA_TYPE_VIDEO,
 +    .id             = AV_CODEC_ID_H264,
 +    .priv_data_size = sizeof(CHDContext),
 +    .init           = init,
 +    .close          = uninit,
 +    .decode         = decode,
 +    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
 +    .flush          = flush,
 +    .long_name      = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (CrystalHD acceleration)"),
 +    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
 +    .priv_class     = &h264_class,
 +};
 +#endif
 +
 +#if CONFIG_MPEG2_CRYSTALHD_DECODER
 +static AVClass mpeg2_class = {
 +    "mpeg2_crystalhd",
 +    av_default_item_name,
 +    options,
 +    LIBAVUTIL_VERSION_INT,
 +};
 +
 +AVCodec ff_mpeg2_crystalhd_decoder = {
 +    .name           = "mpeg2_crystalhd",
 +    .type           = AVMEDIA_TYPE_VIDEO,
 +    .id             = AV_CODEC_ID_MPEG2VIDEO,
 +    .priv_data_size = sizeof(CHDContext),
 +    .init           = init,
 +    .close          = uninit,
 +    .decode         = decode,
 +    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
 +    .flush          = flush,
 +    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-2 Video (CrystalHD acceleration)"),
 +    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
 +    .priv_class     = &mpeg2_class,
 +};
 +#endif
 +
 +#if CONFIG_MPEG4_CRYSTALHD_DECODER
 +static AVClass mpeg4_class = {
 +    "mpeg4_crystalhd",
 +    av_default_item_name,
 +    options,
 +    LIBAVUTIL_VERSION_INT,
 +};
 +
 +AVCodec ff_mpeg4_crystalhd_decoder = {
 +    .name           = "mpeg4_crystalhd",
 +    .type           = AVMEDIA_TYPE_VIDEO,
 +    .id             = AV_CODEC_ID_MPEG4,
 +    .priv_data_size = sizeof(CHDContext),
 +    .init           = init,
 +    .close          = uninit,
 +    .decode         = decode,
 +    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
 +    .flush          = flush,
 +    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 (CrystalHD acceleration)"),
 +    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
 +    .priv_class     = &mpeg4_class,
 +};
 +#endif
 +
 +#if CONFIG_MSMPEG4_CRYSTALHD_DECODER
 +static AVClass msmpeg4_class = {
 +    "msmpeg4_crystalhd",
 +    av_default_item_name,
 +    options,
 +    LIBAVUTIL_VERSION_INT,
 +};
 +
 +AVCodec ff_msmpeg4_crystalhd_decoder = {
 +    .name           = "msmpeg4_crystalhd",
 +    .type           = AVMEDIA_TYPE_VIDEO,
 +    .id             = AV_CODEC_ID_MSMPEG4V3,
 +    .priv_data_size = sizeof(CHDContext),
 +    .init           = init,
 +    .close          = uninit,
 +    .decode         = decode,
 +    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL,
 +    .flush          = flush,
 +    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 Microsoft variant version 3 (CrystalHD acceleration)"),
 +    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
 +    .priv_class     = &msmpeg4_class,
 +};
 +#endif
 +
 +#if CONFIG_VC1_CRYSTALHD_DECODER
 +static AVClass vc1_class = {
 +    "vc1_crystalhd",
 +    av_default_item_name,
 +    options,
 +    LIBAVUTIL_VERSION_INT,
 +};
 +
 +AVCodec ff_vc1_crystalhd_decoder = {
 +    .name           = "vc1_crystalhd",
 +    .type           = AVMEDIA_TYPE_VIDEO,
 +    .id             = AV_CODEC_ID_VC1,
 +    .priv_data_size = sizeof(CHDContext),
 +    .init           = init,
 +    .close          = uninit,
 +    .decode         = decode,
 +    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
 +    .flush          = flush,
 +    .long_name      = NULL_IF_CONFIG_SMALL("SMPTE VC-1 (CrystalHD acceleration)"),
 +    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
 +    .priv_class     = &vc1_class,
 +};
 +#endif
 +
 +#if CONFIG_WMV3_CRYSTALHD_DECODER
 +static AVClass wmv3_class = {
 +    "wmv3_crystalhd",
 +    av_default_item_name,
 +    options,
 +    LIBAVUTIL_VERSION_INT,
 +};
 +
 +AVCodec ff_wmv3_crystalhd_decoder = {
 +    .name           = "wmv3_crystalhd",
 +    .type           = AVMEDIA_TYPE_VIDEO,
 +    .id             = AV_CODEC_ID_WMV3,
 +    .priv_data_size = sizeof(CHDContext),
 +    .init           = init,
 +    .close          = uninit,
 +    .decode         = decode,
 +    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
 +    .flush          = flush,
 +    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 9 (CrystalHD acceleration)"),
 +    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
 +    .priv_class     = &wmv3_class,
 +};
 +#endif
Simple merge
@@@ -88,15 -87,15 +87,15 @@@ static void fill_picture_parameters(str
          }
      }
  
-     pp->wFrameWidthInMbsMinus1        = s->mb_width  - 1;
-     pp->wFrameHeightInMbsMinus1       = s->mb_height - 1;
+     pp->wFrameWidthInMbsMinus1        = h->mb_width  - 1;
+     pp->wFrameHeightInMbsMinus1       = h->mb_height - 1;
      pp->num_ref_frames                = h->sps.ref_frame_count;
  
-     pp->wBitFields                    = ((s->picture_structure != PICT_FRAME) <<  0) |
+     pp->wBitFields                    = ((h->picture_structure != PICT_FRAME) <<  0) |
                                          ((h->sps.mb_aff &&
-                                         (s->picture_structure == PICT_FRAME)) <<  1) |
+                                         (h->picture_structure == PICT_FRAME)) <<  1) |
                                          (h->sps.residual_color_transform_flag <<  2) |
 -                                        /* sp_for_switch_flag (not implemented by Libav) */
 +                                        /* sp_for_switch_flag (not implemented by FFmpeg) */
                                          (0                                    <<  3) |
                                          (h->sps.chroma_format_idc             <<  4) |
                                          ((h->nal_ref_idc != 0)                <<  6) |
@@@ -259,8 -257,8 +257,8 @@@ static void fill_slice_long(AVCodecCont
              }
          }
      }
 -    slice->slice_qs_delta    = 0; /* XXX not implemented by Libav */
 +    slice->slice_qs_delta    = 0; /* XXX not implemented by FFmpeg */
-     slice->slice_qp_delta    = s->qscale - h->pps.init_qp;
+     slice->slice_qp_delta    = h->qscale - h->pps.init_qp;
      slice->redundant_pic_cnt = h->redundant_pic_count;
      if (h->slice_type == AV_PICTURE_TYPE_B)
          slice->direct_spatial_mv_pred_flag = h->direct_spatial_mv_pred;
Simple merge
Simple merge
Simple merge
@@@ -96,28 -83,19 +96,27 @@@ static void h264_er_decode_mb(void *opa
                                int mb_x, int mb_y, int mb_intra, int mb_skipped)
  {
      H264Context    *h = opaque;
-     MpegEncContext *s = &h->s;
  
-     s->mb_x  = mb_x;
-     s->mb_y  = mb_y;
-     h->mb_xy = s->mb_x + s->mb_y * s->mb_stride;
+     h->mb_x  = mb_x;
+     h->mb_y  = mb_y;
+     h->mb_xy = mb_x + mb_y * h->mb_stride;
      memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache));
 -    assert(ref >= 0);
 +    av_assert1(ref >= 0);
      /* FIXME: It is possible albeit uncommon that slice references
       * differ between slices. We take the easy approach and ignore
       * it for now. If this turns out to have any relevance in
       * practice then correct remapping should be added. */
      if (ref >= h->ref_count[0])
          ref = 0;
-         av_log(s->avctx, AV_LOG_DEBUG, "Reference not available for error concealing\n");
 +    if (!h->ref_list[0][ref].f.data[0]) {
-         av_log(s->avctx, AV_LOG_DEBUG, "Reference invalid\n");
++        av_log(h->avctx, AV_LOG_DEBUG, "Reference not available for error concealing\n");
 +        ref = 0;
 +    }
 +    if ((h->ref_list[0][ref].f.reference&3) != 3) {
-     fill_rectangle(&s->current_picture.f.ref_index[0][4 * h->mb_xy],
++        av_log(h->avctx, AV_LOG_DEBUG, "Reference invalid\n");
 +        return;
 +    }
+     fill_rectangle(&h->cur_pic.f.ref_index[0][4 * h->mb_xy],
                     2, 2, 2, ref, 1);
      fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
      fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8,
      ff_h264_hl_decode_mb(h);
  }
  
+ void ff_h264_draw_horiz_band(H264Context *h, int y, int height)
+ {
+     ff_draw_horiz_band(h->avctx, &h->dsp, &h->cur_pic,
+                        h->ref_list[0][0].f.data[0] ? &h->ref_list[0][0] : NULL,
+                        y, height, h->picture_structure, h->first_field, 1,
+                        h->low_delay, h->mb_height * 16, h->mb_width * 16);
+ }
+ static void free_frame_buffer(H264Context *h, Picture *pic)
+ {
++    pic->period_since_free = 0;
+     ff_thread_release_buffer(h->avctx, &pic->f);
+     av_freep(&pic->f.hwaccel_picture_private);
+ }
+ static void free_picture(H264Context *h, Picture *pic)
+ {
+     int i;
+     if (pic->f.data[0])
+         free_frame_buffer(h, pic);
+     av_freep(&pic->qscale_table_base);
+     pic->f.qscale_table = NULL;
+     av_freep(&pic->mb_type_base);
+     pic->f.mb_type = NULL;
+     for (i = 0; i < 2; i++) {
+         av_freep(&pic->motion_val_base[i]);
+         av_freep(&pic->f.ref_index[i]);
+         pic->f.motion_val[i] = NULL;
+     }
+ }
+ static void release_unused_pictures(H264Context *h, int remove_current)
+ {
+     int i;
+     /* release non reference frames */
+     for (i = 0; i < h->picture_count; i++) {
+         if (h->DPB[i].f.data[0] && !h->DPB[i].f.reference &&
+             (!h->DPB[i].owner2 || h->DPB[i].owner2 == h) &&
+             (remove_current || &h->DPB[i] != h->cur_pic_ptr)) {
+             free_frame_buffer(h, &h->DPB[i]);
+         }
+     }
+ }
+ static int alloc_scratch_buffers(H264Context *h, int linesize)
+ {
+     int alloc_size = FFALIGN(FFABS(linesize) + 32, 32);
+     if (h->bipred_scratchpad)
+         return 0;
+     h->bipred_scratchpad = av_malloc(16 * 6 * alloc_size);
+     // edge emu needs blocksize + filter length - 1
+     // (= 21x21 for  h264)
+     h->edge_emu_buffer = av_mallocz(alloc_size * 2 * 21);
+     h->me.scratchpad   = av_mallocz(alloc_size * 2 * 16 * 2);
+     if (!h->bipred_scratchpad || !h->edge_emu_buffer || !h->me.scratchpad) {
+         av_freep(&h->bipred_scratchpad);
+         av_freep(&h->edge_emu_buffer);
+         av_freep(&h->me.scratchpad);
+         return AVERROR(ENOMEM);
+     }
+     h->me.temp = h->me.scratchpad;
+     return 0;
+ }
+ static int alloc_picture(H264Context *h, Picture *pic)
+ {
+     const int big_mb_num    = h->mb_stride * (h->mb_height + 1) + 1;
+     const int mb_array_size = h->mb_stride * h->mb_height;
+     const int b4_stride     = h->mb_width * 4 + 1;
+     const int b4_array_size = b4_stride * h->mb_height * 4;
+     int i, ret = 0;
+     av_assert0(!pic->f.data[0]);
+     if (h->avctx->hwaccel) {
+         const AVHWAccel *hwaccel = h->avctx->hwaccel;
+         av_assert0(!pic->f.hwaccel_picture_private);
+         if (hwaccel->priv_data_size) {
+             pic->f.hwaccel_picture_private = av_mallocz(hwaccel->priv_data_size);
+             if (!pic->f.hwaccel_picture_private)
+                 return AVERROR(ENOMEM);
+         }
+     }
+     ret = ff_thread_get_buffer(h->avctx, &pic->f);
+     if (ret < 0)
+         goto fail;
+     h->linesize   = pic->f.linesize[0];
+     h->uvlinesize = pic->f.linesize[1];
+     if (pic->f.qscale_table == NULL) {
+         FF_ALLOCZ_OR_GOTO(h->avctx, pic->qscale_table_base,
+                           (big_mb_num + h->mb_stride) * sizeof(uint8_t),
+                           fail)
+         FF_ALLOCZ_OR_GOTO(h->avctx, pic->mb_type_base,
+                           (big_mb_num + h->mb_stride) * sizeof(uint32_t),
+                           fail)
+         pic->f.mb_type = pic->mb_type_base + 2 * h->mb_stride + 1;
+         pic->f.qscale_table = pic->qscale_table_base + 2 * h->mb_stride + 1;
+         for (i = 0; i < 2; i++) {
+             FF_ALLOCZ_OR_GOTO(h->avctx, pic->motion_val_base[i],
+                               2 * (b4_array_size + 4) * sizeof(int16_t),
+                               fail)
+             pic->f.motion_val[i] = pic->motion_val_base[i] + 4;
+             FF_ALLOCZ_OR_GOTO(h->avctx, pic->f.ref_index[i],
+                               4 * mb_array_size * sizeof(uint8_t), fail)
+         }
+         pic->f.motion_subsample_log2 = 2;
+         pic->f.qstride = h->mb_stride;
+     }
+     pic->owner2 = h;
+     return 0;
+ fail:
+     free_frame_buffer(h, pic);
+     return (ret < 0) ? ret : AVERROR(ENOMEM);
+ }
+ static inline int pic_is_unused(H264Context *h, Picture *pic)
+ {
++    if (   (h->avctx->active_thread_type & FF_THREAD_FRAME)
++        && pic->f.qscale_table //check if the frame has anything allocated
++        && pic->period_since_free < h->avctx->thread_count)
++        return 0;
+     if (pic->f.data[0] == NULL)
+         return 1;
+     if (pic->needs_realloc && !(pic->f.reference & DELAYED_PIC_REF))
+         if (!pic->owner2 || pic->owner2 == h)
+             return 1;
+     return 0;
+ }
+ static int find_unused_picture(H264Context *h)
+ {
+     int i;
+     for (i = h->picture_range_start; i < h->picture_range_end; i++) {
+         if (pic_is_unused(h, &h->DPB[i]))
+             break;
+     }
+     if (i == h->picture_range_end)
+         return AVERROR_INVALIDDATA;
+     if (h->DPB[i].needs_realloc) {
+         h->DPB[i].needs_realloc = 0;
+         free_picture(h, &h->DPB[i]);
+         avcodec_get_frame_defaults(&h->DPB[i].f);
+     }
+     return i;
+ }
  /**
   * Check if the top & left blocks are available if needed and
   * change the dc mode so it only uses the available blocks.
@@@ -290,17 -428,6 +450,17 @@@ const uint8_t *ff_h264_decode_nal(H264C
      if (dst == NULL)
          return NULL;
  
-         if(h->s.avctx->flags2 & CODEC_FLAG2_FAST){
 +    if(i>=length-1){ //no escaped 0
 +        *dst_length= length;
 +        *consumed= length+1; //+1 for the header
++        if(h->avctx->flags2 & CODEC_FLAG2_FAST){
 +            return src;
 +        }else{
 +            memcpy(dst, src, length);
 +            return dst;
 +        }
 +    }
 +
      memcpy(dst, src, i);
      si = di = i;
      while (si + 2 < length) {
@@@ -793,22 -915,23 +948,21 @@@ static av_always_inline void prefetch_m
  {
      /* fetch pixels for estimated mv 4 macroblocks ahead
       * optimized for 64byte cache lines */
-     MpegEncContext *const s = &h->s;
      const int refn = h->ref_cache[list][scan8[0]];
      if (refn >= 0) {
-         const int mx  = (h->mv_cache[list][scan8[0]][0] >> 2) + 16 * s->mb_x + 8;
-         const int my  = (h->mv_cache[list][scan8[0]][1] >> 2) + 16 * s->mb_y;
+         const int mx  = (h->mv_cache[list][scan8[0]][0] >> 2) + 16 * h->mb_x + 8;
+         const int my  = (h->mv_cache[list][scan8[0]][1] >> 2) + 16 * h->mb_y;
          uint8_t **src = h->ref_list[list][refn].f.data;
          int off       = (mx << pixel_shift) +
-                         (my + (s->mb_x & 3) * 4) * h->mb_linesize +
+                         (my + (h->mb_x & 3) * 4) * h->mb_linesize +
                          (64 << pixel_shift);
-         s->vdsp.prefetch(src[0] + off, s->linesize, 4);
+         h->vdsp.prefetch(src[0] + off, h->linesize, 4);
          if (chroma_idc == 3 /* yuv444 */) {
-             s->vdsp.prefetch(src[1] + off, s->linesize, 4);
-             s->vdsp.prefetch(src[2] + off, s->linesize, 4);
+             h->vdsp.prefetch(src[1] + off, h->linesize, 4);
+             h->vdsp.prefetch(src[2] + off, h->linesize, 4);
          } else {
-             off= (((mx>>1)+64)<<pixel_shift) + ((my>>1) + (s->mb_x&7))*s->uvlinesize;
-             s->vdsp.prefetch(src[1] + off, src[2] - src[1], 2);
 -            off = ((mx >> 1) << pixel_shift) +
 -                  ((my >> 1) + (h->mb_x & 7)) * h->uvlinesize +
 -                  (64 << pixel_shift);
++            off= (((mx>>1)+64)<<pixel_shift) + ((my>>1) + (h->mb_x&7))*h->uvlinesize;
+             h->vdsp.prefetch(src[1] + off, src[2] - src[1], 2);
          }
      }
  }
@@@ -922,28 -1066,27 +1097,27 @@@ static void init_dequant_tables(H264Con
  
  int ff_h264_alloc_tables(H264Context *h)
  {
-     MpegEncContext *const s = &h->s;
-     const int big_mb_num    = s->mb_stride * (s->mb_height + 1);
-     const int row_mb_num    = 2*s->mb_stride*FFMAX(s->avctx->thread_count, 1);
-     int x, y;
+     const int big_mb_num    = h->mb_stride * (h->mb_height + 1);
 -    const int row_mb_num    = h->mb_stride * 2 * h->avctx->thread_count;
++    const int row_mb_num    = 2*h->mb_stride*FFMAX(h->avctx->thread_count, 1);
+     int x, y, i;
  
-     FF_ALLOCZ_OR_GOTO(h->s.avctx, h->intra4x4_pred_mode,
+     FF_ALLOCZ_OR_GOTO(h->avctx, h->intra4x4_pred_mode,
                        row_mb_num * 8 * sizeof(uint8_t), fail)
-     FF_ALLOCZ_OR_GOTO(h->s.avctx, h->non_zero_count,
+     FF_ALLOCZ_OR_GOTO(h->avctx, h->non_zero_count,
                        big_mb_num * 48 * sizeof(uint8_t), fail)
-     FF_ALLOCZ_OR_GOTO(h->s.avctx, h->slice_table_base,
-                       (big_mb_num + s->mb_stride) * sizeof(*h->slice_table_base), fail)
-     FF_ALLOCZ_OR_GOTO(h->s.avctx, h->cbp_table,
+     FF_ALLOCZ_OR_GOTO(h->avctx, h->slice_table_base,
+                       (big_mb_num + h->mb_stride) * sizeof(*h->slice_table_base), fail)
+     FF_ALLOCZ_OR_GOTO(h->avctx, h->cbp_table,
                        big_mb_num * sizeof(uint16_t), fail)
-     FF_ALLOCZ_OR_GOTO(h->s.avctx, h->chroma_pred_mode_table,
+     FF_ALLOCZ_OR_GOTO(h->avctx, h->chroma_pred_mode_table,
                        big_mb_num * sizeof(uint8_t), fail)
-     FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[0],
+     FF_ALLOCZ_OR_GOTO(h->avctx, h->mvd_table[0],
                        16 * row_mb_num * sizeof(uint8_t), fail);
-     FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[1],
+     FF_ALLOCZ_OR_GOTO(h->avctx, h->mvd_table[1],
                        16 * row_mb_num * sizeof(uint8_t), fail);
-     FF_ALLOCZ_OR_GOTO(h->s.avctx, h->direct_table,
+     FF_ALLOCZ_OR_GOTO(h->avctx, h->direct_table,
                        4 * big_mb_num * sizeof(uint8_t), fail);
-     FF_ALLOCZ_OR_GOTO(h->s.avctx, h->list_counts,
+     FF_ALLOCZ_OR_GOTO(h->avctx, h->list_counts,
                        big_mb_num * sizeof(uint8_t), fail)
  
      memset(h->slice_table_base, -1,
@@@ -1027,43 -1228,35 +1259,43 @@@ static int decode_nal_units(H264Contex
  
  static av_cold void common_init(H264Context *h)
  {
-     MpegEncContext *const s = &h->s;
  
-     s->width    = s->avctx->width;
-     s->height   = s->avctx->height;
-     s->codec_id = s->avctx->codec->id;
+     h->width    = h->avctx->width;
+     h->height   = h->avctx->height;
  
-     s->avctx->bits_per_raw_sample = 8;
+     h->bit_depth_luma    = 8;
+     h->chroma_format_idc = 1;
++    h->avctx->bits_per_raw_sample = 8;
 +    h->cur_chroma_format_idc = 1;
 +
      ff_h264dsp_init(&h->h264dsp, 8, 1);
 +    av_assert0(h->sps.bit_depth_chroma == 0);
      ff_h264chroma_init(&h->h264chroma, h->sps.bit_depth_chroma);
      ff_h264qpel_init(&h->h264qpel, 8);
-     ff_h264_pred_init(&h->hpc, s->codec_id, 8, 1);
+     ff_h264_pred_init(&h->hpc, h->avctx->codec_id, 8, 1);
  
      h->dequant_coeff_pps = -1;
-     s->unrestricted_mv   = 1;
  
-     s->dsp.dct_bits = 16;
++    h->dsp.dct_bits = 16;
      /* needed so that IDCT permutation is known early */
-     ff_dsputil_init(&s->dsp, s->avctx);
-     ff_videodsp_init(&s->vdsp, 8);
+     ff_dsputil_init(&h->dsp, h->avctx);
+     ff_videodsp_init(&h->vdsp, 8);
  
      memset(h->pps.scaling_matrix4, 16, 6 * 16 * sizeof(uint8_t));
      memset(h->pps.scaling_matrix8, 16, 2 * 64 * sizeof(uint8_t));
  }
  
 -int ff_h264_decode_extradata(H264Context *h)
 +int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size)
  {
-     AVCodecContext *avctx = h->s.avctx;
+     AVCodecContext *avctx = h->avctx;
  
 -    if (avctx->extradata[0] == 1) {
 +    if (!buf || size <= 0)
 +        return -1;
 +
 +    if (buf[0] == 1) {
          int i, cnt, nalsize;
 -        unsigned char *p = avctx->extradata;
 +        const unsigned char *p = buf;
  
          h->is_avc = 1;
  
@@@ -1147,29 -1339,21 +1379,29 @@@ av_cold int ff_h264_decode_init(AVCodec
      h->x264_build   = -1;
      ff_h264_reset_sei(h);
      if (avctx->codec_id == AV_CODEC_ID_H264) {
 -        if (avctx->ticks_per_frame == 1)
 -            h->avctx->time_base.den *= 2;
 +        if (avctx->ticks_per_frame == 1) {
-             if(s->avctx->time_base.den < INT_MAX/2) {
-                 s->avctx->time_base.den *= 2;
++            if(h->avctx->time_base.den < INT_MAX/2) {
++                h->avctx->time_base.den *= 2;
 +            } else
-                 s->avctx->time_base.num /= 2;
++                h->avctx->time_base.num /= 2;
 +        }
          avctx->ticks_per_frame = 2;
      }
  
      if (avctx->extradata_size > 0 && avctx->extradata &&
 -        ff_h264_decode_extradata(h))
 +        ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size) < 0) {
 +        ff_h264_free_context(h);
          return -1;
 +    }
  
      if (h->sps.bitstream_restriction_flag &&
-         s->avctx->has_b_frames < h->sps.num_reorder_frames) {
-         s->avctx->has_b_frames = h->sps.num_reorder_frames;
-         s->low_delay           = 0;
+         h->avctx->has_b_frames < h->sps.num_reorder_frames) {
+         h->avctx->has_b_frames = h->sps.num_reorder_frames;
+         h->low_delay           = 0;
      }
  
 +    ff_init_cabac_states();
 +
      return 0;
  }
  
@@@ -1231,11 -1420,11 +1468,11 @@@ static int decode_update_thread_context
                                          const AVCodecContext *src)
  {
      H264Context *h = dst->priv_data, *h1 = src->priv_data;
-     MpegEncContext *const s = &h->s, *const s1 = &h1->s;
-     int inited = s->context_initialized, err;
+     int inited = h->context_initialized, err = 0;
+     int context_reinitialized = 0;
      int i;
  
 -    if (dst == src || !h1->context_initialized)
 +    if (dst == src)
          return 0;
  
      if (inited &&
  
          av_freep(&h->bipred_scratchpad);
  
-         s->width     = s1->width;
-         s->height    = s1->height;
-         s->mb_height = s1->mb_height;
+         h->width     = h1->width;
+         h->height    = h1->height;
+         h->mb_height = h1->mb_height;
+         h->mb_width  = h1->mb_width;
+         h->mb_num    = h1->mb_num;
+         h->mb_stride = h1->mb_stride;
          h->b_stride  = h1->b_stride;
 +        // SPS/PPS
 +        copy_parameter_set((void **)h->sps_buffers, (void **)h1->sps_buffers,
 +                        MAX_SPS_COUNT, sizeof(SPS));
 +        h->sps = h1->sps;
 +        copy_parameter_set((void **)h->pps_buffers, (void **)h1->pps_buffers,
 +                        MAX_PPS_COUNT, sizeof(PPS));
 +        h->pps = h1->pps;
  
          if ((err = h264_slice_header_init(h, 1)) < 0) {
-             av_log(h->s.avctx, AV_LOG_ERROR, "h264_slice_header_init() failed");
+             av_log(h->avctx, AV_LOG_ERROR, "h264_slice_header_init() failed");
              return err;
          }
-         h->context_reinitialized = 1;
+         context_reinitialized = 1;
  
 -        /* update linesize on resize. The decoder doesn't
 -         * necessarily call ff_h264_frame_start in the new thread */
 -        h->linesize   = h1->linesize;
 -        h->uvlinesize = h1->uvlinesize;
 -
 -        /* copy block_offset since frame_start may not be called */
 -        memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset));
++#if 0
 +        h264_set_parameter_from_sps(h);
 +        //Note we set context_reinitialized which will cause h264_set_parameter_from_sps to be reexecuted
 +        h->cur_chroma_format_idc = h1->cur_chroma_format_idc;
++#endif
      }
-     s->linesize   = s1->linesize;
-     s->uvlinesize = s1->uvlinesize;
 +    /* update linesize on resize for h264. The h264 decoder doesn't
 +     * necessarily call ff_MPV_frame_start in the new thread */
++    h->linesize   = h1->linesize;
++    h->uvlinesize = h1->uvlinesize;
 +
 +    /* copy block_offset since frame_start may not be called */
 +    memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset));
  
-     err = ff_mpeg_update_thread_context(dst, src);
-     if (err)
-         return err;
      if (!inited) {
          for (i = 0; i < MAX_SPS_COUNT; i++)
              av_freep(h->sps_buffers + i);
          for (i = 0; i < MAX_PPS_COUNT; i++)
              av_freep(h->pps_buffers + i);
  
-         // copy all fields after MpegEnc, except mb
-         memcpy(&h->s + 1, &h1->s + 1,
-                offsetof(H264Context, mb) - sizeof(MpegEncContext));
-         av_assert0(&h->cabac == &h->mb_padding + 1);
 -        memcpy(h, h1, sizeof(*h1));
++        memcpy(h, h1, offsetof(H264Context, mb));
 +        memcpy(&h->cabac, &h1->cabac,
 +               sizeof(H264Context) - offsetof(H264Context, cabac));
++        av_assert0(&h->cabac == &h->mb_padding + 1);
++
          memset(h->sps_buffers, 0, sizeof(h->sps_buffers));
          memset(h->pps_buffers, 0, sizeof(h->pps_buffers));
-         if (s1->context_initialized) {
 +
 -        h->avctx = dst;
 -        h->DPB   = NULL;
+         memset(&h->er, 0, sizeof(h->er));
+         memset(&h->me, 0, sizeof(h->me));
++        h->avctx = dst;
++        h->DPB   = NULL;
++
++        if (h1->context_initialized) {
+         h->context_initialized = 0;
+         h->picture_range_start  += MAX_PICTURE_COUNT;
+         h->picture_range_end    += MAX_PICTURE_COUNT;
+         h->cur_pic.f.extended_data = h->cur_pic.f.data;
          if (ff_h264_alloc_tables(h) < 0) {
              av_log(dst, AV_LOG_ERROR, "Could not allocate memory for h264\n");
              return AVERROR(ENOMEM);
          }
          context_init(h);
 +        }
  
          for (i = 0; i < 2; i++) {
              h->rbsp_buffer[i]      = NULL;
              h->rbsp_buffer_size[i] = 0;
          }
          h->bipred_scratchpad = NULL;
+         h->edge_emu_buffer   = NULL;
  
          h->thread_context[0] = h;
 -
 -        h->dsp.clear_blocks(h->mb);
 -        h->dsp.clear_blocks(h->mb + (24 * 16 << h->pixel_shift));
 -        h->context_initialized = 1;
++        h->context_initialized = h1->context_initialized;
+     }
+     h->avctx->coded_height  = h1->avctx->coded_height;
+     h->avctx->coded_width   = h1->avctx->coded_width;
+     h->avctx->width         = h1->avctx->width;
+     h->avctx->height        = h1->avctx->height;
+     h->coded_picture_number = h1->coded_picture_number;
+     h->first_field          = h1->first_field;
+     h->picture_structure    = h1->picture_structure;
+     h->qscale               = h1->qscale;
+     h->droppable            = h1->droppable;
+     h->data_partitioning    = h1->data_partitioning;
+     h->low_delay            = h1->low_delay;
+     memcpy(h->DPB, h1->DPB, h1->picture_count * sizeof(*h1->DPB));
+     // reset s->picture[].f.extended_data to s->picture[].f.data
 -    for (i = 0; i < h->picture_count; i++)
++    for (i = 0; i < h->picture_count; i++) {
+         h->DPB[i].f.extended_data = h->DPB[i].f.data;
++        h->DPB[i].period_since_free ++;
 +    }
  
+     h->cur_pic_ptr     = REBASE_PICTURE(h1->cur_pic_ptr, h, h1);
+     h->cur_pic = h1->cur_pic;
+     h->cur_pic.f.extended_data = h->cur_pic.f.data;
+     h->workaround_bugs = h1->workaround_bugs;
+     h->low_delay       = h1->low_delay;
+     h->droppable       = h1->droppable;
      /* frame_start may not be called for the next thread (if it's decoding
       * a bottom field) so this has to be allocated here */
-     if (!h->bipred_scratchpad && s->linesize)
-         h->bipred_scratchpad = av_malloc(16 * 6 * s->linesize);
 -    err = alloc_scratch_buffers(h, h1->linesize);
 -    if (err < 0)
 -        return err;
++    if (h1->linesize) {
++        err = alloc_scratch_buffers(h, h1->linesize);
++        if (err < 0)
++            return err;
++    }
  
      // extradata/NAL handling
      h->is_avc = h1->is_avc;
      copy_fields(h, h1, ref2frm, intra_gb);
      copy_fields(h, h1, short_ref, cabac_init_idc);
  
-     copy_picture_range(h->short_ref, h1->short_ref, 32, s, s1);
-     copy_picture_range(h->long_ref, h1->long_ref, 32, s, s1);
+     copy_picture_range(h->short_ref, h1->short_ref, 32, h, h1);
+     copy_picture_range(h->long_ref, h1->long_ref, 32, h, h1);
      copy_picture_range(h->delayed_pic, h1->delayed_pic,
-                        MAX_DELAYED_PIC_COUNT + 2, s, s1);
+                        MAX_DELAYED_PIC_COUNT + 2, h, h1);
  
      h->last_slice_type = h1->last_slice_type;
 +    h->sync            = h1->sync;
  
-     if (!s->current_picture_ptr)
+     if (context_reinitialized)
+         h264_set_parameter_from_sps(h);
+     if (!h->cur_pic_ptr)
          return 0;
  
-     if (!s->droppable) {
+     if (!h->droppable) {
          err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
          h->prev_poc_msb = h->poc_msb;
          h->prev_poc_lsb = h->poc_lsb;
  
  int ff_h264_frame_start(H264Context *h)
  {
-     MpegEncContext *const s = &h->s;
-     int i;
+     Picture *pic;
+     int i, ret;
      const int pixel_shift = h->pixel_shift;
-     if (ff_MPV_frame_start(s, s->avctx) < 0)
 +    int c[4] = {
 +        1<<(h->sps.bit_depth_luma-1),
 +        1<<(h->sps.bit_depth_chroma-1),
 +        1<<(h->sps.bit_depth_chroma-1),
 +        -1
 +    };
 +
-     if(!h->sync)
-         avpriv_color_frame(&h->s.current_picture_ptr->f, c);
++    if (!ff_thread_can_start_frame(h->avctx)) {
++        av_log(h->avctx, AV_LOG_ERROR, "Attempt to start a frame outside SETUP state\n");
 +        return -1;
-     ff_mpeg_er_frame_start(s);
++    }
+     release_unused_pictures(h, 1);
+     h->cur_pic_ptr = NULL;
+     i = find_unused_picture(h);
+     if (i < 0) {
+         av_log(h->avctx, AV_LOG_ERROR, "no frame buffer available\n");
+         return i;
+     }
+     pic = &h->DPB[i];
+     pic->f.reference            = h->droppable ? 0 : h->picture_structure;
+     pic->f.coded_picture_number = h->coded_picture_number++;
+     pic->field_picture          = h->picture_structure != PICT_FRAME;
 +
      /*
-      * ff_MPV_frame_start uses pict_type to derive key_frame.
-      * This is incorrect for H.264; IDR markings must be used.
-      * Zero here; IDR markings per slice in frame or fields are ORed in later.
+      * Zero key_frame here; IDR markings per slice in frame or fields are ORed
+      * in later.
       * See decode_nal_units().
       */
-     s->current_picture_ptr->f.key_frame = 0;
-     s->current_picture_ptr->sync        = 0;
-     s->current_picture_ptr->mmco_reset  = 0;
+     pic->f.key_frame = 0;
++    pic->sync        = 0;
+     pic->mmco_reset  = 0;
+     if ((ret = alloc_picture(h, pic)) < 0)
+         return ret;
++    if(!h->sync)
++        avpriv_color_frame(&pic->f, c);
  
-     assert(s->linesize && s->uvlinesize);
+     h->cur_pic_ptr = pic;
+     h->cur_pic     = *h->cur_pic_ptr;
+     h->cur_pic.f.extended_data = h->cur_pic.f.data;
+     ff_er_frame_start(&h->er);
+     assert(h->linesize && h->uvlinesize);
  
      for (i = 0; i < 16; i++) {
-         h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * s->linesize * ((scan8[i] - scan8[0]) >> 3);
-         h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * s->linesize * ((scan8[i] - scan8[0]) >> 3);
+         h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
+         h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
      }
      for (i = 0; i < 16; i++) {
          h->block_offset[16 + i]      =
      /* Some macroblocks can be accessed before they're available in case
       * of lost slices, MBAFF or threading. */
      memset(h->slice_table, -1,
-            (s->mb_height * s->mb_stride - 1) * sizeof(*h->slice_table));
+            (h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table));
  
--    // s->decode = (s->flags & CODEC_FLAG_PSNR) || !s->encoding ||
--    //             s->current_picture.f.reference /* || h->contains_intra */ || 1;
++    // s->decode = (h->flags & CODEC_FLAG_PSNR) || !s->encoding ||
++    //             h->cur_pic.f.reference /* || h->contains_intra */ || 1;
  
      /* We mark the current picture as non-reference after allocating it, so
       * that if we break out due to an error it can be released automatically
   */
  static void decode_postinit(H264Context *h, int setup_finished)
  {
-     MpegEncContext *const s = &h->s;
-     Picture *out = s->current_picture_ptr;
-     Picture *cur = s->current_picture_ptr;
+     Picture *out = h->cur_pic_ptr;
+     Picture *cur = h->cur_pic_ptr;
      int i, pics, out_of_order, out_idx;
 -    int invalid = 0, cnt = 0;
  
-     s->current_picture_ptr->f.qscale_type = FF_QSCALE_TYPE_H264;
-     s->current_picture_ptr->f.pict_type   = s->pict_type;
+     h->cur_pic_ptr->f.qscale_type = FF_QSCALE_TYPE_H264;
+     h->cur_pic_ptr->f.pict_type   = h->pict_type;
  
      if (h->next_output_pic)
          return;
      /* Sort B-frames into display order */
  
      if (h->sps.bitstream_restriction_flag &&
-         s->avctx->has_b_frames < h->sps.num_reorder_frames) {
-         s->avctx->has_b_frames = h->sps.num_reorder_frames;
-         s->low_delay           = 0;
+         h->avctx->has_b_frames < h->sps.num_reorder_frames) {
+         h->avctx->has_b_frames = h->sps.num_reorder_frames;
+         h->low_delay           = 0;
      }
  
-     if (s->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT &&
+     if (h->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT &&
          !h->sps.bitstream_restriction_flag) {
-         s->avctx->has_b_frames = MAX_DELAYED_PIC_COUNT - 1;
-         s->low_delay           = 0;
+         h->avctx->has_b_frames = MAX_DELAYED_PIC_COUNT - 1;
+         h->low_delay           = 0;
      }
  
-         av_log(s->avctx, AV_LOG_VERBOSE, "Invalid POC %d<%d\n", cur->poc, h->last_pocs[0]);
 +    for (i = 0; 1; i++) {
 +        if(i == MAX_DELAYED_PIC_COUNT || cur->poc < h->last_pocs[i]){
 +            if(i)
 +                h->last_pocs[i-1] = cur->poc;
 +            break;
 +        } else if(i) {
 +            h->last_pocs[i-1]= h->last_pocs[i];
 +        }
 +    }
 +    out_of_order = MAX_DELAYED_PIC_COUNT - i;
 +    if(   cur->f.pict_type == AV_PICTURE_TYPE_B
 +       || (h->last_pocs[MAX_DELAYED_PIC_COUNT-2] > INT_MIN && h->last_pocs[MAX_DELAYED_PIC_COUNT-1] - h->last_pocs[MAX_DELAYED_PIC_COUNT-2] > 2))
 +        out_of_order = FFMAX(out_of_order, 1);
 +    if (out_of_order == MAX_DELAYED_PIC_COUNT) {
-     } else if(s->avctx->has_b_frames < out_of_order && !h->sps.bitstream_restriction_flag){
-         av_log(s->avctx, AV_LOG_VERBOSE, "Increasing reorder buffer to %d\n", out_of_order);
-         s->avctx->has_b_frames = out_of_order;
-         s->low_delay = 0;
++        av_log(h->avctx, AV_LOG_VERBOSE, "Invalid POC %d<%d\n", cur->poc, h->last_pocs[0]);
 +        for (i = 1; i < MAX_DELAYED_PIC_COUNT; i++)
 +            h->last_pocs[i] = INT_MIN;
 +        h->last_pocs[0] = cur->poc;
 +        cur->mmco_reset = 1;
++    } else if(h->avctx->has_b_frames < out_of_order && !h->sps.bitstream_restriction_flag){
++        av_log(h->avctx, AV_LOG_VERBOSE, "Increasing reorder buffer to %d\n", out_of_order);
++        h->avctx->has_b_frames = out_of_order;
++        h->low_delay = 0;
 +    }
 +
      pics = 0;
      while (h->delayed_pic[pics])
          pics++;
              out     = h->delayed_pic[i];
              out_idx = i;
          }
-     if (s->avctx->has_b_frames == 0 &&
+     if (h->avctx->has_b_frames == 0 &&
 -        (h->delayed_pic[0]->f.key_frame || h->mmco_reset))
 +        (h->delayed_pic[0]->f.key_frame || h->delayed_pic[0]->mmco_reset))
          h->next_outputed_poc = INT_MIN;
 -    out_of_order = !out->f.key_frame && !h->mmco_reset &&
 -                   (out->poc < h->next_outputed_poc);
 -
 -    if (h->sps.bitstream_restriction_flag &&
 -        h->avctx->has_b_frames >= h->sps.num_reorder_frames) {
 -    } else if (out_of_order && pics - 1 == h->avctx->has_b_frames &&
 -               h->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT) {
 -        if (invalid + cnt < MAX_DELAYED_PIC_COUNT) {
 -            h->avctx->has_b_frames = FFMAX(h->avctx->has_b_frames, cnt);
 -        }
 -        h->low_delay = 0;
 -    } else if (h->low_delay &&
 -               ((h->next_outputed_poc != INT_MIN &&
 -                 out->poc > h->next_outputed_poc + 2) ||
 -                cur->f.pict_type == AV_PICTURE_TYPE_B)) {
 -        h->low_delay = 0;
 -        h->avctx->has_b_frames++;
 -    }
 +    out_of_order = out->poc < h->next_outputed_poc;
  
-     if (out_of_order || pics > s->avctx->has_b_frames) {
 -    if (pics > h->avctx->has_b_frames) {
++    if (out_of_order || pics > h->avctx->has_b_frames) {
          out->f.reference &= ~DELAYED_PIC_REF;
          // for frame threading, the owner must be the second field's thread or
          // else the first thread can release the picture and reuse it unsafely
          for (i = out_idx; h->delayed_pic[i]; i++)
              h->delayed_pic[i] = h->delayed_pic[i + 1];
      }
-     if (!out_of_order && pics > s->avctx->has_b_frames) {
 -    memmove(h->last_pocs, &h->last_pocs[1],
 -            sizeof(*h->last_pocs) * (MAX_DELAYED_PIC_COUNT - 1));
 -    h->last_pocs[MAX_DELAYED_PIC_COUNT - 1] = cur->poc;
+     if (!out_of_order && pics > h->avctx->has_b_frames) {
          h->next_output_pic = out;
 -        if (out->mmco_reset) {
 -            if (out_idx > 0) {
 -                h->next_outputed_poc                    = out->poc;
 -                h->delayed_pic[out_idx - 1]->mmco_reset = out->mmco_reset;
 -            } else {
 -                h->next_outputed_poc = INT_MIN;
 -            }
 -        } else {
 -            if (out_idx == 0 && pics > 1 && h->delayed_pic[0]->f.key_frame) {
 -                h->next_outputed_poc = INT_MIN;
 -            } else {
 -                h->next_outputed_poc = out->poc;
 -            }
 -        }
 -        h->mmco_reset = 0;
 +        if (out_idx == 0 && h->delayed_pic[0] && (h->delayed_pic[0]->f.key_frame || h->delayed_pic[0]->mmco_reset)) {
 +            h->next_outputed_poc = INT_MIN;
 +        } else
 +            h->next_outputed_poc = out->poc;
      } else {
-         av_log(s->avctx, AV_LOG_DEBUG, "no picture %s\n", out_of_order ? "ooo" : "");
 -        av_log(h->avctx, AV_LOG_DEBUG, "no picture\n");
++        av_log(h->avctx, AV_LOG_DEBUG, "no picture %s\n", out_of_order ? "ooo" : "");
 +    }
 +
 +    if (h->next_output_pic && h->next_output_pic->sync) {
 +        h->sync |= 2;
      }
  
      if (setup_finished)
@@@ -1907,7 -2158,7 +2212,7 @@@ static av_always_inline void hl_decode_
                      uint64_t tr_high;
                      if (dir == DIAG_DOWN_LEFT_PRED || dir == VERT_LEFT_PRED) {
                          const int topright_avail = (h->topright_samples_available << i) & 0x8000;
-                         av_assert2(s->mb_y || linesize <= block_offset[i]);
 -                        assert(h->mb_y || linesize <= block_offset[i]);
++                        av_assert2(h->mb_y || linesize <= block_offset[i]);
                          if (!topright_avail) {
                              if (pixel_shift) {
                                  tr_high  = ((uint16_t *)ptr)[3 - linesize / 2] * 0x0001000100010001ULL;
@@@ -2218,15 -2463,9 +2519,15 @@@ static void flush_change(H264Context *h
      h->outputed_poc = h->next_outputed_poc = INT_MIN;
      h->prev_interlaced_frame = 1;
      idr(h);
 -    if (h->cur_pic_ptr)
 +    h->prev_frame_num = -1;
-     if (h->s.current_picture_ptr) {
-         h->s.current_picture_ptr->f.reference = 0;
++    if (h->cur_pic_ptr) {
+         h->cur_pic_ptr->f.reference = 0;
 +        for (j=i=0; h->delayed_pic[i]; i++)
-             if (h->delayed_pic[i] != h->s.current_picture_ptr)
++            if (h->delayed_pic[i] != h->cur_pic_ptr)
 +                h->delayed_pic[j++] = h->delayed_pic[i];
 +        h->delayed_pic[j] = NULL;
 +    }
-     h->s.first_field = 0;
+     h->first_field = 0;
      memset(h->ref_list[0], 0, sizeof(h->ref_list[0]));
      memset(h->ref_list[1], 0, sizeof(h->ref_list[1]));
      memset(h->default_ref_list[0], 0, sizeof(h->default_ref_list[0]));
@@@ -2417,10 -2664,36 +2730,36 @@@ static int field_end(H264Context *h, in
       * past end by one (callers fault) and resync_mb_y != 0
       * causes problems for the first MB line, too.
       */
-     if (!FIELD_PICTURE && h->current_slice && !h->sps.new)
-         ff_er_frame_end(&s->er);
-     ff_MPV_frame_end(s);
 -    if (!FIELD_PICTURE) {
++    if (!FIELD_PICTURE && h->current_slice && !h->sps.new) {
+         h->er.cur_pic  = h->cur_pic_ptr;
+         h->er.last_pic = h->ref_count[0] ? &h->ref_list[0][0] : NULL;
+         h->er.next_pic = h->ref_count[1] ? &h->ref_list[1][0] : NULL;
+         ff_er_frame_end(&h->er);
+     }
+     /* redraw edges for the frame if decoding didn't complete */
+     if (h->er.error_count &&
+         !h->avctx->hwaccel &&
+         !(h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) &&
+         h->cur_pic_ptr->f.reference &&
+         !(h->flags & CODEC_FLAG_EMU_EDGE)) {
+         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(h->avctx->pix_fmt);
+         int hshift = desc->log2_chroma_w;
+         int vshift = desc->log2_chroma_h;
+         h->dsp.draw_edges(h->cur_pic.f.data[0], h->linesize,
+                           h->mb_width * 16, h->mb_height * 16,
+                           EDGE_WIDTH, EDGE_WIDTH,
+                           EDGE_TOP | EDGE_BOTTOM);
+         h->dsp.draw_edges(h->cur_pic.f.data[1], h->uvlinesize,
+                           (h->mb_width * 16) >> hshift, (h->mb_height * 16) >> vshift,
+                           EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
+                           EDGE_TOP | EDGE_BOTTOM);
+         h->dsp.draw_edges(h->cur_pic.f.data[2], h->uvlinesize,
+                           (h->mb_width * 16) >> hshift, (h->mb_height * 16) >> vshift,
+                           EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
+                           EDGE_TOP | EDGE_BOTTOM);
+     }
+     emms_c();
  
      h->current_slice = 0;
  
@@@ -2517,10 -2779,8 +2845,10 @@@ static int h264_set_parameter_from_sps(
                     "VDPAU decoding does not support video colorspace.\n");
              return AVERROR_INVALIDDATA;
          }
 -        if (h->sps.bit_depth_luma >= 8 && h->sps.bit_depth_luma <= 10) {
 +        if (h->sps.bit_depth_luma >= 8 && h->sps.bit_depth_luma <= 14 &&
 +            h->sps.bit_depth_luma != 11 && h->sps.bit_depth_luma != 13 &&
 +                (h->sps.bit_depth_luma != 9 || !CHROMA422)) {
-             s->avctx->bits_per_raw_sample = h->sps.bit_depth_luma;
+             h->avctx->bits_per_raw_sample = h->sps.bit_depth_luma;
              h->cur_chroma_format_idc      = h->sps.chroma_format_idc;
              h->pixel_shift                = h->sps.bit_depth_luma > 8;
  
@@@ -2568,45 -2827,20 +2895,45 @@@ static enum PixelFormat get_pixel_forma
          else
              return AV_PIX_FMT_YUV420P10;
          break;
 -    case 8:
 +    case 12:
          if (CHROMA444) {
-             if (s->avctx->colorspace == AVCOL_SPC_RGB) {
+             if (h->avctx->colorspace == AVCOL_SPC_RGB) {
 -                return AV_PIX_FMT_GBRP;
 +                return AV_PIX_FMT_GBRP12;
              } else
 -                return h->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ444P
 -                                                                 : AV_PIX_FMT_YUV444P;
 +                return AV_PIX_FMT_YUV444P12;
 +        } else if (CHROMA422)
 +            return AV_PIX_FMT_YUV422P12;
 +        else
 +            return AV_PIX_FMT_YUV420P12;
 +        break;
 +    case 14:
 +        if (CHROMA444) {
-             if (s->avctx->colorspace == AVCOL_SPC_RGB) {
++            if (h->avctx->colorspace == AVCOL_SPC_RGB) {
 +                return AV_PIX_FMT_GBRP14;
 +            } else
 +                return AV_PIX_FMT_YUV444P14;
 +        } else if (CHROMA422)
 +            return AV_PIX_FMT_YUV422P14;
 +        else
 +            return AV_PIX_FMT_YUV420P14;
 +        break;
 +    case 8:
 +        if (CHROMA444) {
-             if (s->avctx->colorspace == AVCOL_SPC_RGB) {
-                 av_log(h->s.avctx, AV_LOG_DEBUG, "Detected GBR colorspace.\n");
++            if (h->avctx->colorspace == AVCOL_SPC_RGB) {
++                av_log(h->avctx, AV_LOG_DEBUG, "Detected GBR colorspace.\n");
 +                return AV_PIX_FMT_GBR24P;
-             } else if (s->avctx->colorspace == AVCOL_SPC_YCGCO) {
-                 av_log(h->s.avctx, AV_LOG_WARNING, "Detected unsupported YCgCo colorspace.\n");
++            } else if (h->avctx->colorspace == AVCOL_SPC_YCGCO) {
++                av_log(h->avctx, AV_LOG_WARNING, "Detected unsupported YCgCo colorspace.\n");
 +            }
-             return s->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ444P
++            return h->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ444P
 +                                                                : AV_PIX_FMT_YUV444P;
          } else if (CHROMA422) {
-             return s->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ422P
+             return h->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ422P
                                                               : AV_PIX_FMT_YUV422P;
          } else {
-             return s->avctx->get_format(s->avctx, s->avctx->codec->pix_fmts ?
-                                         s->avctx->codec->pix_fmts :
-                                         s->avctx->color_range == AVCOL_RANGE_JPEG ?
+             return h->avctx->get_format(h->avctx, h->avctx->codec->pix_fmts ?
+                                         h->avctx->codec->pix_fmts :
+                                         h->avctx->color_range == AVCOL_RANGE_JPEG ?
                                          hwaccel_pixfmt_list_h264_jpeg_420 :
                                          ff_hwaccel_pixfmt_list_420);
          }
  
  static int h264_slice_header_init(H264Context *h, int reinit)
  {
-     MpegEncContext *const s  = &h->s;
-     int i, ret;
+     int nb_slices = (HAVE_THREADS &&
+                      h->avctx->active_thread_type & FF_THREAD_SLICE) ?
+                     h->avctx->thread_count : 1;
+     int i;
  
-     if(   FFALIGN(s->avctx->width , 16                                 ) == s->width
-         && FFALIGN(s->avctx->height, 16*(2 - h->sps.frame_mbs_only_flag)) == s->height
 -    avcodec_set_dimensions(h->avctx, h->width, h->height);
++    if(    FFALIGN(h->avctx->width , 16                                 ) == h->width
++        && FFALIGN(h->avctx->height, 16*(2 - h->sps.frame_mbs_only_flag)) == h->height
 +        && !h->sps.crop_right && !h->sps.crop_bottom
-         && (s->avctx->width != s->width || s->avctx->height && s->height)
++        && (h->avctx->width != h->width || h->avctx->height && h->height)
 +    ) {
-         av_log(h->s.avctx, AV_LOG_DEBUG, "Using externally provided dimensions\n");
-         s->avctx->coded_width  = s->width;
-         s->avctx->coded_height = s->height;
++        av_log(h->avctx, AV_LOG_DEBUG, "Using externally provided dimensions\n");
++        h->avctx->coded_width  = h->width;
++        h->avctx->coded_height = h->height;
 +    } else{
-         avcodec_set_dimensions(s->avctx, s->width, s->height);
-         s->avctx->width  -= (2>>CHROMA444)*FFMIN(h->sps.crop_right, (8<<CHROMA444)-1);
-         s->avctx->height -= (1<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1) * (2 - h->sps.frame_mbs_only_flag);
++        avcodec_set_dimensions(h->avctx, h->width, h->height);
++        h->avctx->width  -= (2>>CHROMA444)*FFMIN(h->sps.crop_right, (8<<CHROMA444)-1);
++        h->avctx->height -= (1<<h->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>h->chroma_y_shift)-1) * (2 - h->sps.frame_mbs_only_flag);
 +    }
 +
-     s->avctx->sample_aspect_ratio = h->sps.sar;
-     av_assert0(s->avctx->sample_aspect_ratio.den);
+     h->avctx->sample_aspect_ratio = h->sps.sar;
+     av_assert0(h->avctx->sample_aspect_ratio.den);
+     av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt,
+                                      &h->chroma_x_shift, &h->chroma_y_shift);
  
      if (h->sps.timing_info_present_flag) {
          int64_t den = h->sps.time_scale;
              c->sps         = h->sps;
              c->pps         = h->pps;
              c->pixel_shift = h->pixel_shift;
 +            c->cur_chroma_format_idc = h->cur_chroma_format_idc;
+             c->width       = h->width;
+             c->height      = h->height;
+             c->linesize    = h->linesize;
+             c->uvlinesize  = h->uvlinesize;
+             c->chroma_x_shift = h->chroma_x_shift;
+             c->chroma_y_shift = h->chroma_y_shift;
+             c->qscale      = h->qscale;
+             c->droppable   = h->droppable;
+             c->data_partitioning = h->data_partitioning;
+             c->low_delay   = h->low_delay;
+             c->mb_width    = h->mb_width;
+             c->mb_height   = h->mb_height;
+             c->mb_stride   = h->mb_stride;
+             c->mb_num      = h->mb_num;
+             c->flags       = h->flags;
+             c->workaround_bugs = h->workaround_bugs;
+             c->pict_type   = h->pict_type;
              init_scan_tables(c);
              clone_tables(c, h, i);
+             c->context_initialized = 1;
          }
  
-         for (i = 0; i < s->slice_context_count; i++)
+         for (i = 0; i < h->slice_context_count; i++)
              if (context_init(h->thread_context[i]) < 0) {
-                 av_log(h->s.avctx, AV_LOG_ERROR, "context_init() failed.\n");
+                 av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
                  return -1;
              }
      }
   */
  static int decode_slice_header(H264Context *h, H264Context *h0)
  {
-     MpegEncContext *const s  = &h->s;
-     MpegEncContext *const s0 = &h0->s;
      unsigned int first_mb_in_slice;
      unsigned int pps_id;
 -    int num_ref_idx_active_override_flag, max_refs, ret;
 +    int num_ref_idx_active_override_flag, ret;
      unsigned int slice_type, tmp, i, j;
      int default_ref_list_done = 0;
      int last_pic_structure, last_pic_droppable;
 +    int must_reinit;
      int needs_reinit = 0;
  
-     s->me.qpel_put = h->h264qpel.put_h264_qpel_pixels_tab;
-     s->me.qpel_avg = h->h264qpel.avg_h264_qpel_pixels_tab;
+     h->me.qpel_put = h->h264qpel.put_h264_qpel_pixels_tab;
+     h->me.qpel_avg = h->h264qpel.avg_h264_qpel_pixels_tab;
  
-     first_mb_in_slice = get_ue_golomb_long(&s->gb);
 -    first_mb_in_slice = get_ue_golomb(&h->gb);
++    first_mb_in_slice = get_ue_golomb_long(&h->gb);
  
      if (first_mb_in_slice == 0) { // FIXME better field boundary detection
          if (h0->current_slice && FIELD_PICTURE) {
          }
      }
  
-     slice_type = get_ue_golomb_31(&s->gb);
+     slice_type = get_ue_golomb_31(&h->gb);
      if (slice_type > 9) {
-         av_log(h->s.avctx, AV_LOG_ERROR,
+         av_log(h->avctx, AV_LOG_ERROR,
                 "slice type too large (%d) at %d %d\n",
-                slice_type, s->mb_x, s->mb_y);
 -               h->slice_type, h->mb_x, h->mb_y);
++               slice_type, h->mb_x, h->mb_y);
          return -1;
      }
      if (slice_type > 4) {
      h->slice_type_nos = slice_type & 3;
  
      // to make a few old functions happy, it's wrong though
-     s->pict_type = h->slice_type;
+     h->pict_type = h->slice_type;
  
-     pps_id = get_ue_golomb(&s->gb);
+     pps_id = get_ue_golomb(&h->gb);
      if (pps_id >= MAX_PPS_COUNT) {
-         av_log(h->s.avctx, AV_LOG_ERROR, "pps_id %d out of range\n", pps_id);
 -        av_log(h->avctx, AV_LOG_ERROR, "pps_id out of range\n");
++        av_log(h->avctx, AV_LOG_ERROR, "pps_id %d out of range\n", pps_id);
          return -1;
      }
      if (!h0->pps_buffers[pps_id]) {
          h->current_sps_id = h->pps.sps_id;
          h->sps            = *h0->sps_buffers[h->pps.sps_id];
  
-         if (s->mb_width  != h->sps.mb_width ||
-             s->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) ||
-             s->avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||
++        if (h->mb_width  != h->sps.mb_width ||
++            h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) ||
++            h->avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||
 +            h->cur_chroma_format_idc != h->sps.chroma_format_idc
 +        )
 +            needs_reinit = 1;
 +
+         if (h->bit_depth_luma    != h->sps.bit_depth_luma ||
+             h->chroma_format_idc != h->sps.chroma_format_idc) {
+             h->bit_depth_luma    = h->sps.bit_depth_luma;
+             h->chroma_format_idc = h->sps.chroma_format_idc;
+             needs_reinit         = 1;
+         }
          if ((ret = h264_set_parameter_from_sps(h)) < 0)
              return ret;
      }
  
-     s->avctx->profile = ff_h264_get_profile(&h->sps);
-     s->avctx->level   = h->sps.level_idc;
-     s->avctx->refs    = h->sps.ref_frame_count;
+     h->avctx->profile = ff_h264_get_profile(&h->sps);
+     h->avctx->level   = h->sps.level_idc;
+     h->avctx->refs    = h->sps.ref_frame_count;
  
-     must_reinit = (s->context_initialized &&
-                     (   16*h->sps.mb_width != s->avctx->coded_width
-                      || 16*h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) != s->avctx->coded_height
-                      || s->avctx->bits_per_raw_sample != h->sps.bit_depth_luma
 -    if (h->mb_width  != h->sps.mb_width ||
 -        h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag))
 -        needs_reinit = 1;
++    must_reinit = (h->context_initialized &&
++                    (   16*h->sps.mb_width != h->avctx->coded_width
++                     || 16*h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) != h->avctx->coded_height
++                     || h->avctx->bits_per_raw_sample != h->sps.bit_depth_luma
 +                     || h->cur_chroma_format_idc != h->sps.chroma_format_idc
-                      || av_cmp_q(h->sps.sar, s->avctx->sample_aspect_ratio)));
-     if (h0->s.avctx->pix_fmt != get_pixel_format(h0))
++                     || av_cmp_q(h->sps.sar, h->avctx->sample_aspect_ratio)));
++    if (h0->avctx->pix_fmt != get_pixel_format(h0))
 +        must_reinit = 1;
  
-     s->mb_width  = h->sps.mb_width;
-     s->mb_height = h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);
+     h->mb_width  = h->sps.mb_width;
+     h->mb_height = h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);
+     h->mb_num    = h->mb_width * h->mb_height;
+     h->mb_stride = h->mb_width + 1;
  
-     h->b_stride = s->mb_width * 4;
+     h->b_stride = h->mb_width * 4;
  
-     s->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p
+     h->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p
  
-     s->width  = 16 * s->mb_width;
-     s->height = 16 * s->mb_height;
 -    h->width = 16 * h->mb_width - (2 >> CHROMA444) * FFMIN(h->sps.crop_right, (8 << CHROMA444) - 1);
 -    if (h->sps.frame_mbs_only_flag)
 -        h->height = 16 * h->mb_height - (1 << h->chroma_y_shift) * FFMIN(h->sps.crop_bottom, (16 >> h->chroma_y_shift) - 1);
 -    else
 -        h->height = 16 * h->mb_height - (2 << h->chroma_y_shift) * FFMIN(h->sps.crop_bottom, (16 >> h->chroma_y_shift) - 1);
 -
 -    if (FFALIGN(h->avctx->width,  16) == h->width &&
 -        FFALIGN(h->avctx->height, 16) == h->height) {
 -        h->width  = h->avctx->width;
 -        h->height = h->avctx->height;
 -    }
++    h->width  = 16 * h->mb_width;
++    h->height = 16 * h->mb_height;
  
      if (h->sps.video_signal_type_present_flag) {
-         s->avctx->color_range = h->sps.full_range>0 ? AVCOL_RANGE_JPEG
 -        h->avctx->color_range = h->sps.full_range ? AVCOL_RANGE_JPEG
 -                                                  : AVCOL_RANGE_MPEG;
++        h->avctx->color_range = h->sps.full_range>0 ? AVCOL_RANGE_JPEG
 +                                                    : AVCOL_RANGE_MPEG;
          if (h->sps.colour_description_present_flag) {
-             if (s->avctx->colorspace != h->sps.colorspace)
+             if (h->avctx->colorspace != h->sps.colorspace)
                  needs_reinit = 1;
-             s->avctx->color_primaries = h->sps.color_primaries;
-             s->avctx->color_trc       = h->sps.color_trc;
-             s->avctx->colorspace      = h->sps.colorspace;
+             h->avctx->color_primaries = h->sps.color_primaries;
+             h->avctx->color_trc       = h->sps.color_trc;
+             h->avctx->colorspace      = h->sps.colorspace;
          }
      }
  
-     if (s->context_initialized &&
+     if (h->context_initialized &&
 -        (h->width  != h->avctx->width   ||
 -         h->height != h->avctx->height  ||
 -         needs_reinit)) {
 +        (
 +         needs_reinit                   ||
 +         must_reinit)) {
  
          if (h != h0) {
-             av_log(s->avctx, AV_LOG_ERROR, "changing width/height on "
+             av_log(h->avctx, AV_LOG_ERROR, "changing width/height on "
                     "slice %d\n", h0->current_slice + 1);
              return AVERROR_INVALIDDATA;
          }
  
      h->mb_mbaff        = 0;
      h->mb_aff_frame    = 0;
-     last_pic_structure = s0->picture_structure;
-     last_pic_droppable = s0->droppable;
-     s->droppable       = h->nal_ref_idc == 0;
+     last_pic_structure = h0->picture_structure;
+     last_pic_droppable = h0->droppable;
+     h->droppable       = h->nal_ref_idc == 0;
      if (h->sps.frame_mbs_only_flag) {
-         s->picture_structure = PICT_FRAME;
+         h->picture_structure = PICT_FRAME;
      } else {
-             av_log(h->s.avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n");
 +        if (!h->sps.direct_8x8_inference_flag && slice_type == AV_PICTURE_TYPE_B) {
-         if (get_bits1(&s->gb)) { // field_pic_flag
-             s->picture_structure = PICT_TOP_FIELD + get_bits1(&s->gb); // bottom_field_flag
++            av_log(h->avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n");
 +            return -1;
 +        }
+         if (get_bits1(&h->gb)) { // field_pic_flag
+             h->picture_structure = PICT_TOP_FIELD + get_bits1(&h->gb); // bottom_field_flag
          } else {
-             s->picture_structure = PICT_FRAME;
+             h->picture_structure = PICT_FRAME;
              h->mb_aff_frame      = h->sps.mb_aff;
          }
      }
           * Here, we're using that to see if we should mark previously
           * decode frames as "finished".
           * We have to do that before the "dummy" in-between frame allocation,
--         * since that can modify s->current_picture_ptr. */
-         if (s0->first_field) {
-             assert(s0->current_picture_ptr);
-             assert(s0->current_picture_ptr->f.data[0]);
-             assert(s0->current_picture_ptr->f.reference != DELAYED_PIC_REF);
++         * since that can modify h->cur_pic_ptr. */
+         if (h0->first_field) {
+             assert(h0->cur_pic_ptr);
+             assert(h0->cur_pic_ptr->f.data[0]);
+             assert(h0->cur_pic_ptr->f.reference != DELAYED_PIC_REF);
  
              /* Mark old field/frame as completed */
-             if (!last_pic_droppable && s0->current_picture_ptr->owner2 == s0) {
-                 ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
+             if (!last_pic_droppable && h0->cur_pic_ptr->owner2 == h0) {
+                 ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX,
                                            last_pic_structure == PICT_BOTTOM_FIELD);
              }
  
              }
          }
  
-         while (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0 && !s0->first_field &&
 -        while (h->frame_num != h->prev_frame_num &&
++        while (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0 && !h0->first_field &&
                 h->frame_num != (h->prev_frame_num + 1) % (1 << h->sps.log2_max_frame_num)) {
              Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;
-             av_log(h->s.avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",
+             av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",
                     h->frame_num, h->prev_frame_num);
 +            if (!h->sps.gaps_in_frame_num_allowed_flag)
 +                for(i=0; i<FF_ARRAY_ELEMS(h->last_pocs); i++)
 +                    h->last_pocs[i] = INT_MIN;
              if (ff_h264_frame_start(h) < 0)
                  return -1;
              h->prev_frame_num++;
          /* See if we have a decoded first field looking for a pair...
           * We're using that to see whether to continue decoding in that
           * frame, or to allocate a new one. */
-         if (s0->first_field) {
-             assert(s0->current_picture_ptr);
-             assert(s0->current_picture_ptr->f.data[0]);
-             assert(s0->current_picture_ptr->f.reference != DELAYED_PIC_REF);
+         if (h0->first_field) {
+             assert(h0->cur_pic_ptr);
+             assert(h0->cur_pic_ptr->f.data[0]);
+             assert(h0->cur_pic_ptr->f.reference != DELAYED_PIC_REF);
  
              /* figure out if we have a complementary field pair */
-             if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) {
+             if (!FIELD_PICTURE || h->picture_structure == last_pic_structure) {
                  /* Previous field is unmatched. Don't display it, but let it
                   * remain for reference if marked as such. */
-                 s0->current_picture_ptr = NULL;
-                 s0->first_field         = FIELD_PICTURE;
+                 h0->cur_pic_ptr = NULL;
+                 h0->first_field = FIELD_PICTURE;
              } else {
-                 if (s0->current_picture_ptr->frame_num != h->frame_num) {
-                     ff_thread_report_progress((AVFrame*)s0->current_picture_ptr, INT_MAX,
-                                               s0->picture_structure==PICT_BOTTOM_FIELD);
+                 if (h0->cur_pic_ptr->frame_num != h->frame_num) {
++                    ff_thread_report_progress((AVFrame*)h0->cur_pic_ptr, INT_MAX,
++                                              h0->picture_structure==PICT_BOTTOM_FIELD);
                      /* This and the previous field had different frame_nums.
                       * Consider this field first in pair. Throw away previous
                       * one except for reference purposes. */
      if (h != h0 && (ret = clone_slice(h, h0)) < 0)
          return ret;
  
-     s->current_picture_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup
+     h->cur_pic_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup
  
-     av_assert1(s->mb_num == s->mb_width * s->mb_height);
-     if (first_mb_in_slice << FIELD_OR_MBAFF_PICTURE >= s->mb_num ||
-         first_mb_in_slice >= s->mb_num) {
-         av_log(h->s.avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n");
 -    assert(h->mb_num == h->mb_width * h->mb_height);
++    av_assert1(h->mb_num == h->mb_width * h->mb_height);
+     if (first_mb_in_slice << FIELD_OR_MBAFF_PICTURE >= h->mb_num ||
+         first_mb_in_slice >= h->mb_num) {
+         av_log(h->avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n");
          return -1;
      }
-     s->resync_mb_x = s->mb_x =  first_mb_in_slice % s->mb_width;
-     s->resync_mb_y = s->mb_y = (first_mb_in_slice / s->mb_width) << FIELD_OR_MBAFF_PICTURE;
-     if (s->picture_structure == PICT_BOTTOM_FIELD)
-         s->resync_mb_y = s->mb_y = s->mb_y + 1;
-     av_assert1(s->mb_y < s->mb_height);
+     h->resync_mb_x = h->mb_x =  first_mb_in_slice % h->mb_width;
+     h->resync_mb_y = h->mb_y = (first_mb_in_slice / h->mb_width) << FIELD_OR_MBAFF_PICTURE;
+     if (h->picture_structure == PICT_BOTTOM_FIELD)
+         h->resync_mb_y = h->mb_y = h->mb_y + 1;
 -    assert(h->mb_y < h->mb_height);
++    av_assert1(h->mb_y < h->mb_height);
  
-     if (s->picture_structure == PICT_FRAME) {
+     if (h->picture_structure == PICT_FRAME) {
          h->curr_pic_num = h->frame_num;
          h->max_pic_num  = 1 << h->sps.log2_max_frame_num;
      } else {
      h->ref_count[1] = h->pps.ref_count[1];
  
      if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
-         max[0] = max[1] = s->picture_structure == PICT_FRAME ? 15 : 31;
 +        unsigned max[2];
++        max[0] = max[1] = h->picture_structure == PICT_FRAME ? 15 : 31;
 +
          if (h->slice_type_nos == AV_PICTURE_TYPE_B)
-             h->direct_spatial_mv_pred = get_bits1(&s->gb);
-         num_ref_idx_active_override_flag = get_bits1(&s->gb);
+             h->direct_spatial_mv_pred = get_bits1(&h->gb);
+         num_ref_idx_active_override_flag = get_bits1(&h->gb);
  
          if (num_ref_idx_active_override_flag) {
-             h->ref_count[0] = get_ue_golomb(&s->gb) + 1;
+             h->ref_count[0] = get_ue_golomb(&h->gb) + 1;
 -            if (h->ref_count[0] < 1)
 -                return AVERROR_INVALIDDATA;
              if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
-                 h->ref_count[1] = get_ue_golomb(&s->gb) + 1;
+                 h->ref_count[1] = get_ue_golomb(&h->gb) + 1;
 -                if (h->ref_count[1] < 1)
 -                    return AVERROR_INVALIDDATA;
 -            }
 +            } else
 +                // full range is spec-ok in this case, even for frames
 +                h->ref_count[1] = 1;
 +        }
 +
 +        if (h->ref_count[0]-1 > max[0] || h->ref_count[1]-1 > max[1]){
-             av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow %u > %u or %u > %u\n", h->ref_count[0]-1, max[0], h->ref_count[1]-1, max[1]);
++            av_log(h->avctx, AV_LOG_ERROR, "reference overflow %u > %u or %u > %u\n", h->ref_count[0]-1, max[0], h->ref_count[1]-1, max[1]);
 +            h->ref_count[0] = h->ref_count[1] = 1;
 +            return AVERROR_INVALIDDATA;
          }
  
          if (h->slice_type_nos == AV_PICTURE_TYPE_B)
  
      h0->last_slice_type = slice_type;
      h->slice_num = ++h0->current_slice;
 -    if (h->slice_num >= MAX_SLICES) {
 -        av_log(h->avctx, AV_LOG_ERROR,
 -               "Too many slices, increase MAX_SLICES and recompile\n");
 +
 +    if (h->slice_num)
-         h0->slice_row[(h->slice_num-1)&(MAX_SLICES-1)]= s->resync_mb_y;
-     if (   h0->slice_row[h->slice_num&(MAX_SLICES-1)] + 3 >= s->resync_mb_y
-         && h0->slice_row[h->slice_num&(MAX_SLICES-1)] <= s->resync_mb_y
++        h0->slice_row[(h->slice_num-1)&(MAX_SLICES-1)]= h->resync_mb_y;
++    if (   h0->slice_row[h->slice_num&(MAX_SLICES-1)] + 3 >= h->resync_mb_y
++        && h0->slice_row[h->slice_num&(MAX_SLICES-1)] <= h->resync_mb_y
 +        && h->slice_num >= MAX_SLICES) {
 +        //in case of ASO this check needs to be updated depending on how we decide to assign slice numbers in this case
-         av_log(s->avctx, AV_LOG_WARNING, "Possibly too many slices (%d >= %d), increase MAX_SLICES and recompile if there are artifacts\n", h->slice_num, MAX_SLICES);
++        av_log(h->avctx, AV_LOG_WARNING, "Possibly too many slices (%d >= %d), increase MAX_SLICES and recompile if there are artifacts\n", h->slice_num, MAX_SLICES);
      }
  
      for (j = 0; j < 2; j++) {
@@@ -3444,12 -3659,12 +3783,12 @@@ static av_always_inline void fill_filte
          if (USES_LIST(top_type, list)) {
              const int b_xy  = h->mb2b_xy[top_xy] + 3 * b_stride;
              const int b8_xy = 4 * top_xy + 2;
 -            int (*ref2frm)[64] = h->ref2frm[h->slice_table[top_xy] & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2);
 +            int (*ref2frm)[64] = (void*)(h->ref2frm[h->slice_table[top_xy] & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2));
-             AV_COPY128(mv_dst - 1 * 8, s->current_picture.f.motion_val[list][b_xy + 0]);
+             AV_COPY128(mv_dst - 1 * 8, h->cur_pic.f.motion_val[list][b_xy + 0]);
              ref_cache[0 - 1 * 8] =
-             ref_cache[1 - 1 * 8] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 0]];
+             ref_cache[1 - 1 * 8] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 0]];
              ref_cache[2 - 1 * 8] =
-             ref_cache[3 - 1 * 8] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 1]];
+             ref_cache[3 - 1 * 8] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 1]];
          } else {
              AV_ZERO128(mv_dst - 1 * 8);
              AV_WN32A(&ref_cache[0 - 1 * 8], ((LIST_NOT_USED) & 0xFF) * 0x01010101u);
              if (USES_LIST(left_type[LTOP], list)) {
                  const int b_xy  = h->mb2b_xy[left_xy[LTOP]] + 3;
                  const int b8_xy = 4 * left_xy[LTOP] + 1;
 -                int (*ref2frm)[64] = h->ref2frm[h->slice_table[left_xy[LTOP]] & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2);
 +                int (*ref2frm)[64] =(void*)( h->ref2frm[h->slice_table[left_xy[LTOP]] & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2));
-                 AV_COPY32(mv_dst - 1 +  0, s->current_picture.f.motion_val[list][b_xy + b_stride * 0]);
-                 AV_COPY32(mv_dst - 1 +  8, s->current_picture.f.motion_val[list][b_xy + b_stride * 1]);
-                 AV_COPY32(mv_dst - 1 + 16, s->current_picture.f.motion_val[list][b_xy + b_stride * 2]);
-                 AV_COPY32(mv_dst - 1 + 24, s->current_picture.f.motion_val[list][b_xy + b_stride * 3]);
+                 AV_COPY32(mv_dst - 1 +  0, h->cur_pic.f.motion_val[list][b_xy + b_stride * 0]);
+                 AV_COPY32(mv_dst - 1 +  8, h->cur_pic.f.motion_val[list][b_xy + b_stride * 1]);
+                 AV_COPY32(mv_dst - 1 + 16, h->cur_pic.f.motion_val[list][b_xy + b_stride * 2]);
+                 AV_COPY32(mv_dst - 1 + 24, h->cur_pic.f.motion_val[list][b_xy + b_stride * 3]);
                  ref_cache[-1 +  0] =
-                 ref_cache[-1 +  8] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 2 * 0]];
+                 ref_cache[-1 +  8] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 2 * 0]];
                  ref_cache[-1 + 16] =
-                 ref_cache[-1 + 24] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 2 * 1]];
+                 ref_cache[-1 + 24] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 2 * 1]];
              } else {
                  AV_ZERO32(mv_dst - 1 +  0);
                  AV_ZERO32(mv_dst - 1 +  8);
      }
  
      {
-         int8_t *ref = &s->current_picture.f.ref_index[list][4 * mb_xy];
+         int8_t *ref = &h->cur_pic.f.ref_index[list][4 * mb_xy];
 -        int (*ref2frm)[64] = h->ref2frm[h->slice_num & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2);
 +        int (*ref2frm)[64] = (void*)(h->ref2frm[h->slice_num & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2));
          uint32_t ref01 = (pack16to32(ref2frm[list][ref[0]], ref2frm[list][ref[1]]) & 0x00FF00FF) * 0x0101;
          uint32_t ref23 = (pack16to32(ref2frm[list][ref[2]], ref2frm[list][ref[3]]) & 0x00FF00FF) * 0x0101;
          AV_WN32A(&ref_cache[0 * 8], ref01);
@@@ -3788,25 -3999,23 +4123,24 @@@ static void er_add_slice(H264Context *h
  static int decode_slice(struct AVCodecContext *avctx, void *arg)
  {
      H264Context *h = *(void **)arg;
-     MpegEncContext *const s = &h->s;
-     int lf_x_start = s->mb_x;
+     int lf_x_start = h->mb_x;
  
-     s->mb_skip_run = -1;
+     h->mb_skip_run = -1;
  
-     av_assert0(h->block_offset[15] == (4 * ((scan8[15] - scan8[0]) & 7) << h->pixel_shift) + 4 * s->linesize * ((scan8[15] - scan8[0]) >> 3));
++    av_assert0(h->block_offset[15] == (4 * ((scan8[15] - scan8[0]) & 7) << h->pixel_shift) + 4 * h->linesize * ((scan8[15] - scan8[0]) >> 3));
 +
-     h->is_complex = FRAME_MBAFF || s->picture_structure != PICT_FRAME ||
-                     s->codec_id != AV_CODEC_ID_H264 ||
-                     (CONFIG_GRAY && (s->flags & CODEC_FLAG_GRAY));
+     h->is_complex = FRAME_MBAFF || h->picture_structure != PICT_FRAME ||
+                     avctx->codec_id != AV_CODEC_ID_H264 ||
+                     (CONFIG_GRAY && (h->flags & CODEC_FLAG_GRAY));
  
      if (h->pps.cabac) {
          /* realign */
-         align_get_bits(&s->gb);
+         align_get_bits(&h->gb);
  
          /* init cabac */
 -        ff_init_cabac_states(&h->cabac);
          ff_init_cabac_decoder(&h->cabac,
-                               s->gb.buffer + get_bits_count(&s->gb) / 8,
-                               (get_bits_left(&s->gb) + 7) / 8);
+                               h->gb.buffer + get_bits_count(&h->gb) / 8,
+                               (get_bits_left(&h->gb) + 7) / 8);
  
          ff_h264_init_cabac_states(h);
  
              }
              eos = get_cabac_terminate(&h->cabac);
  
-             if ((s->workaround_bugs & FF_BUG_TRUNCATED) &&
+             if ((h->workaround_bugs & FF_BUG_TRUNCATED) &&
                  h->cabac.bytestream > h->cabac.bytestream_end + 2) {
-                 er_add_slice(h, s->resync_mb_x, s->resync_mb_y, s->mb_x - 1,
-                                 s->mb_y, ER_MB_END);
-                 if (s->mb_x >= lf_x_start)
-                     loop_filter(h, lf_x_start, s->mb_x + 1);
+                 er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x - 1,
+                                 h->mb_y, ER_MB_END);
+                 if (h->mb_x >= lf_x_start)
+                     loop_filter(h, lf_x_start, h->mb_x + 1);
                  return 0;
              }
 -            if (ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 2) {
 +            if (h->cabac.bytestream > h->cabac.bytestream_end + 2 )
-                 av_log(h->s.avctx, AV_LOG_DEBUG, "bytestream overread %td\n", h->cabac.bytestream_end - h->cabac.bytestream);
++                av_log(h->avctx, AV_LOG_DEBUG, "bytestream overread %td\n", h->cabac.bytestream_end - h->cabac.bytestream);
 +            if (ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 4) {
-                 av_log(h->s.avctx, AV_LOG_ERROR,
+                 av_log(h->avctx, AV_LOG_ERROR,
                         "error while decoding MB %d %d, bytestream (%td)\n",
-                        s->mb_x, s->mb_y,
+                        h->mb_x, h->mb_y,
                         h->cabac.bytestream_end - h->cabac.bytestream);
-                 er_add_slice(h, s->resync_mb_x, s->resync_mb_y, s->mb_x,
-                                 s->mb_y, ER_MB_ERROR);
+                 er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
+                                 h->mb_y, ER_MB_ERROR);
                  return -1;
              }
  
                  return -1;
              }
  
-             if (++s->mb_x >= s->mb_width) {
-                 loop_filter(h, lf_x_start, s->mb_x);
-                 s->mb_x = lf_x_start = 0;
+             if (++h->mb_x >= h->mb_width) {
+                 loop_filter(h, lf_x_start, h->mb_x);
+                 h->mb_x = lf_x_start = 0;
                  decode_finish_row(h);
-                 ++s->mb_y;
+                 ++h->mb_y;
                  if (FIELD_OR_MBAFF_PICTURE) {
-                     ++s->mb_y;
-                     if (FRAME_MBAFF && s->mb_y < s->mb_height)
+                     ++h->mb_y;
+                     if (FRAME_MBAFF && h->mb_y < h->mb_height)
                          predict_field_decoding_flag(h);
                  }
-                 if (s->mb_y >= s->mb_height) {
-                     tprintf(s->avctx, "slice end %d %d\n",
-                             get_bits_count(&s->gb), s->gb.size_in_bits);
-                     if (   get_bits_left(&s->gb) == 0
-                         || get_bits_left(&s->gb) > 0 && !(s->avctx->err_recognition & AV_EF_AGGRESSIVE)) {
-                         er_add_slice(h, s->resync_mb_x, s->resync_mb_y,
-                                         s->mb_x - 1, s->mb_y,
+                 if (h->mb_y >= h->mb_height) {
+                     tprintf(h->avctx, "slice end %d %d\n",
+                             get_bits_count(&h->gb), h->gb.size_in_bits);
 -                    if (get_bits_left(&h->gb) == 0) {
++                    if (   get_bits_left(&h->gb) == 0
++                        || get_bits_left(&h->gb) > 0 && !(h->avctx->err_recognition & AV_EF_AGGRESSIVE)) {
+                         er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
+                                         h->mb_x - 1, h->mb_y,
                                          ER_MB_END);
  
                          return 0;
                      } else {
-                         er_add_slice(h, s->resync_mb_x, s->resync_mb_y,
-                                         s->mb_x, s->mb_y,
+                         er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
 -                                        h->mb_x - 1, h->mb_y,
++                                        h->mb_x, h->mb_y,
                                          ER_MB_END);
  
                          return -1;
@@@ -3970,12 -4175,9 +4303,11 @@@ static int execute_decode_slices(H264Co
      if (context_count == 1) {
          return decode_slice(avctx, &h);
      } else {
 +        av_assert0(context_count > 0);
          for (i = 1; i < context_count; i++) {
              hx                    = h->thread_context[i];
-             hx->s.err_recognition = avctx->err_recognition;
-             hx->s.er.error_count  = 0;
+             hx->er.error_count  = 0;
 +            hx->x264_build        = h->x264_build;
          }
  
          avctx->execute(avctx, decode_slice, h->thread_context,
@@@ -4006,18 -4207,12 +4337,18 @@@ static int decode_nal_units(H264Contex
      int pass = !(avctx->active_thread_type & FF_THREAD_FRAME);
      int nals_needed = 0; ///< number of NALs that need decoding before the next frame thread starts
      int nal_index;
 +    int idr_cleared=0;
 +    int first_slice = 0;
 +
 +    h->nal_unit_type= 0;
  
-     if(!s->slice_context_count)
-          s->slice_context_count= 1;
-     h->max_contexts = s->slice_context_count;
-     if (!(s->flags2 & CODEC_FLAG2_CHUNKS)) {
++    if(!h->slice_context_count)
++         h->slice_context_count= 1;
+     h->max_contexts = h->slice_context_count;
+     if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS)) {
          h->current_slice = 0;
-         if (!s->first_field)
-             s->current_picture_ptr = NULL;
+         if (!h->first_field)
+             h->cur_pic_ptr = NULL;
          ff_h264_reset_sei(h);
      }
  
                  goto end;
              }
              i = buf_index + consumed;
-             if ((s->workaround_bugs & FF_BUG_AUTODETECT) && i + 3 < next_avc &&
+             if ((h->workaround_bugs & FF_BUG_AUTODETECT) && i + 3 < next_avc &&
                  buf[i]     == 0x00 && buf[i + 1] == 0x00 &&
                  buf[i + 2] == 0x01 && buf[i + 3] == 0xE0)
-                 s->workaround_bugs |= FF_BUG_TRUNCATED;
+                 h->workaround_bugs |= FF_BUG_TRUNCATED;
  
-             if (!(s->workaround_bugs & FF_BUG_TRUNCATED))
+             if (!(h->workaround_bugs & FF_BUG_TRUNCATED))
 -                while (ptr[dst_length - 1] == 0 && dst_length > 0)
 +                while(dst_length > 0 && ptr[dst_length - 1] == 0)
                      dst_length--;
              bit_length = !dst_length ? 0
                                       : (8 * dst_length -
                                          decode_rbsp_trailing(h, ptr + dst_length - 1));
  
-             if (s->avctx->debug & FF_DEBUG_STARTCODE)
-                 av_log(h->s.avctx, AV_LOG_DEBUG, "NAL %d/%d at %d/%d length %d pass %d\n", hx->nal_unit_type, hx->nal_ref_idc, buf_index, buf_size, dst_length, pass);
+             if (h->avctx->debug & FF_DEBUG_STARTCODE)
 -                av_log(h->avctx, AV_LOG_DEBUG,
 -                       "NAL %d at %d/%d length %d\n",
 -                       hx->nal_unit_type, buf_index, buf_size, dst_length);
++                av_log(h->avctx, AV_LOG_DEBUG, "NAL %d/%d at %d/%d length %d pass %d\n", hx->nal_unit_type, hx->nal_ref_idc, buf_index, buf_size, dst_length, pass);
  
              if (h->is_avc && (nalsize != consumed) && nalsize)
-                 av_log(h->s.avctx, AV_LOG_DEBUG,
+                 av_log(h->avctx, AV_LOG_DEBUG,
                         "AVC: Consumed only %d bytes instead of %d\n",
                         consumed, nalsize);
  
                  case NAL_DPA:
                  case NAL_IDR_SLICE:
                  case NAL_SLICE:
-                     init_get_bits(&hx->s.gb, ptr, bit_length);
-                     if (!get_ue_golomb(&hx->s.gb) || !first_slice)
+                     init_get_bits(&hx->gb, ptr, bit_length);
 -                    if (!get_ue_golomb(&hx->gb))
++                    if (!get_ue_golomb(&hx->gb) || !first_slice)
                          nals_needed = nal_index;
 +                    if (!first_slice)
 +                        first_slice = hx->nal_unit_type;
                  }
                  continue;
              }
                  continue;
  
  again:
 -            /* Ignore every NAL unit type except PPS and SPS during extradata
 +            /* Ignore per frame NAL unit type during extradata
               * parsing. Decoding slices is not possible in codec init
               * with frame-mt */
 -            if (parse_extradata && HAVE_THREADS &&
 -                (h->avctx->active_thread_type & FF_THREAD_FRAME) &&
 -                (hx->nal_unit_type != NAL_PPS &&
 -                 hx->nal_unit_type != NAL_SPS)) {
 -                av_log(avctx, AV_LOG_INFO, "Ignoring NAL unit %d during "
 -                       "extradata parsing\n", hx->nal_unit_type);
 -                hx->nal_unit_type = NAL_FF_IGNORE;
 +            if (parse_extradata) {
 +                switch (hx->nal_unit_type) {
 +                case NAL_IDR_SLICE:
 +                case NAL_SLICE:
 +                case NAL_DPA:
 +                case NAL_DPB:
 +                case NAL_DPC:
 +                case NAL_AUXILIARY_SLICE:
-                     av_log(h->s.avctx, AV_LOG_WARNING, "Ignoring NAL %d in global header/extradata\n", hx->nal_unit_type);
++                    av_log(h->avctx, AV_LOG_WARNING, "Ignoring NAL %d in global header/extradata\n", hx->nal_unit_type);
 +                    hx->nal_unit_type = NAL_FF_IGNORE;
 +                }
              }
 +
              err = 0;
 +
              switch (hx->nal_unit_type) {
              case NAL_IDR_SLICE:
 -                if (h->nal_unit_type != NAL_IDR_SLICE) {
 +                if (first_slice != NAL_IDR_SLICE) {
-                     av_log(h->s.avctx, AV_LOG_ERROR,
+                     av_log(h->avctx, AV_LOG_ERROR,
                             "Invalid mix of idr and non-idr slices\n");
                      buf_index = -1;
                      goto end;
                  }
 -                idr(h); // FIXME ensure we don't lose some frames if there is reordering
 +                if(!idr_cleared)
 +                    idr(h); // FIXME ensure we don't lose some frames if there is reordering
 +                idr_cleared = 1;
              case NAL_SLICE:
-                 init_get_bits(&hx->s.gb, ptr, bit_length);
+                 init_get_bits(&hx->gb, ptr, bit_length);
                  hx->intra_gb_ptr        =
-                     hx->inter_gb_ptr    = &hx->s.gb;
-                 hx->s.data_partitioning = 0;
+                     hx->inter_gb_ptr    = &hx->gb;
+                 hx->data_partitioning = 0;
  
                  if ((err = decode_slice_header(hx, h)))
                      break;
  
-                 s->current_picture_ptr->f.key_frame |=
 +                if (h->sei_recovery_frame_cnt >= 0 && (h->frame_num != h->sei_recovery_frame_cnt || hx->slice_type_nos != AV_PICTURE_TYPE_I))
 +                    h->valid_recovery_point = 1;
 +
 +                if (   h->sei_recovery_frame_cnt >= 0
 +                    && (   h->recovery_frame<0
 +                        || ((h->recovery_frame - h->frame_num) & ((1 << h->sps.log2_max_frame_num)-1)) > h->sei_recovery_frame_cnt)) {
 +                    h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) %
 +                                        (1 << h->sps.log2_max_frame_num);
 +
 +                    if (!h->valid_recovery_point)
 +                        h->recovery_frame = h->frame_num;
 +                }
 +
 -                    (hx->nal_unit_type == NAL_IDR_SLICE) ||
 -                    (h->sei_recovery_frame_cnt >= 0);
+                 h->cur_pic_ptr->f.key_frame |=
-                     s->current_picture_ptr->sync |= 1;
 +                        (hx->nal_unit_type == NAL_IDR_SLICE);
 +
 +                if (h->recovery_frame == h->frame_num) {
-                 h->sync |= !!s->current_picture_ptr->f.key_frame;
-                 h->sync |= 3*!!(s->flags2 & CODEC_FLAG2_SHOW_ALL);
-                 s->current_picture_ptr->sync |= h->sync;
++                    h->cur_pic_ptr->sync |= 1;
 +                    h->recovery_frame = -1;
 +                }
 +
++                h->sync |= !!h->cur_pic_ptr->f.key_frame;
++                h->sync |= 3*!!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL);
++                h->cur_pic_ptr->sync |= h->sync;
  
                  if (h->current_slice == 1) {
-                     if (!(s->flags2 & CODEC_FLAG2_CHUNKS))
+                     if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS))
                          decode_postinit(h, nal_index >= nals_needed);
  
-                     if (s->avctx->hwaccel &&
-                         s->avctx->hwaccel->start_frame(s->avctx, NULL, 0) < 0)
+                     if (h->avctx->hwaccel &&
+                         h->avctx->hwaccel->start_frame(h->avctx, NULL, 0) < 0)
                          return -1;
                      if (CONFIG_H264_VDPAU_DECODER &&
-                         s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
-                         ff_vdpau_h264_picture_start(s);
+                         h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
+                         ff_vdpau_h264_picture_start(h);
                  }
  
                  if (hx->redundant_pic_count == 0 &&
                  init_get_bits(&hx->inter_gb, ptr, bit_length);
                  hx->inter_gb_ptr = &hx->inter_gb;
  
-                 av_log(h->s.avctx, AV_LOG_ERROR, "Partitioned H.264 support is incomplete\n");
++                av_log(h->avctx, AV_LOG_ERROR, "Partitioned H.264 support is incomplete\n");
 +                break;
 +
                  if (hx->redundant_pic_count == 0 &&
                      hx->intra_gb_ptr &&
-                     hx->s.data_partitioning &&
-                     s->current_picture_ptr &&
-                     s->context_initialized &&
+                     hx->data_partitioning &&
+                     h->cur_pic_ptr && h->context_initialized &&
                      (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc) &&
                      (avctx->skip_frame < AVDISCARD_BIDIR  ||
                       hx->slice_type_nos != AV_PICTURE_TYPE_B) &&
                  ff_h264_decode_sei(h);
                  break;
              case NAL_SPS:
-                 init_get_bits(&s->gb, ptr, bit_length);
+                 init_get_bits(&h->gb, ptr, bit_length);
 -                if (ff_h264_decode_seq_parameter_set(h) < 0 &&
 -                    h->is_avc && (nalsize != consumed) && nalsize) {
 +                if (ff_h264_decode_seq_parameter_set(h) < 0 && (h->is_avc ? (nalsize != consumed) && nalsize : 1)) {
-                     av_log(h->s.avctx, AV_LOG_DEBUG,
+                     av_log(h->avctx, AV_LOG_DEBUG,
                             "SPS decoding failure, trying again with the complete NAL\n");
 -                    init_get_bits(&h->gb, buf + buf_index + 1 - consumed,
 -                                  8 * (nalsize - 1));
 +                    if (h->is_avc)
 +                        av_assert0(next_avc - buf_index + consumed == nalsize);
 +                    if ((next_avc - buf_index + consumed - 1) >= INT_MAX/8)
 +                        break;
-                     init_get_bits(&s->gb, &buf[buf_index + 1 - consumed],
++                    init_get_bits(&h->gb, &buf[buf_index + 1 - consumed],
 +                                  8*(next_avc - buf_index + consumed - 1));
                      ff_h264_decode_seq_parameter_set(h);
                  }
  
 -                if (h264_set_parameter_from_sps(h) < 0) {
 -                    buf_index = -1;
 -                    goto end;
 -                }
                  break;
              case NAL_PPS:
-                 init_get_bits(&s->gb, ptr, bit_length);
+                 init_get_bits(&h->gb, ptr, bit_length);
                  ff_h264_decode_picture_parameter_set(h, bit_length);
                  break;
              case NAL_AUD:
@@@ -4362,21 -4510,18 +4692,19 @@@ static int decode_frame(AVCodecContext 
      const uint8_t *buf = avpkt->data;
      int buf_size       = avpkt->size;
      H264Context *h     = avctx->priv_data;
-     MpegEncContext *s  = &h->s;
      AVFrame *pict      = data;
      int buf_index      = 0;
 +    Picture *out;
 +    int i, out_idx;
  
-     s->flags  = avctx->flags;
-     s->flags2 = avctx->flags2;
+     h->flags  = avctx->flags;
  
      /* end of stream, output what is still in the buffers */
 -out:
      if (buf_size == 0) {
 -        Picture *out;
 -        int i, out_idx;
 + out:
  
-         s->current_picture_ptr = NULL;
-         s->first_field = 0;
+         h->cur_pic_ptr = NULL;
++        h->first_field = 0;
  
          // FIXME factorize this with the output code below
          out     = h->delayed_pic[0];
@@@ -4429,15 -4551,14 +4757,15 @@@ not_extra
      if (buf_index < 0)
          return -1;
  
-     if (!s->current_picture_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {
+     if (!h->cur_pic_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {
 -        buf_size = 0;
 +        av_assert0(buf_index <= buf_size);
          goto out;
      }
  
-     if (!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr) {
+     if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) && !h->cur_pic_ptr) {
 -        if (avctx->skip_frame >= AVDISCARD_NONREF)
 -            return 0;
 +        if (avctx->skip_frame >= AVDISCARD_NONREF ||
 +            buf_size >= 4 && !memcmp("Q264", buf, 4))
 +            return buf_size;
          av_log(avctx, AV_LOG_ERROR, "no frame!\n");
          return -1;
      }
              decode_postinit(h, 1);
  
          field_end(h, 0);
-         h->context_reinitialized = 0;
  
 -        if (!h->next_output_pic) {
 -            /* Wait for second field. */
 -            *got_frame = 0;
 -        } else {
 +        /* Wait for second field. */
 +        *got_frame = 0;
 +        if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) {
              *got_frame = 1;
              *pict      = h->next_output_pic->f;
          }
@@@ -4480,14 -4600,16 +4806,17 @@@ av_cold void ff_h264_free_context(H264C
  static av_cold int h264_decode_end(AVCodecContext *avctx)
  {
      H264Context *h    = avctx->priv_data;
-     MpegEncContext *s = &h->s;
+     int i;
  
 +    ff_h264_remove_all_refs(h);
      ff_h264_free_context(h);
  
-     ff_MPV_common_end(s);
-     // memset(h, 0, sizeof(H264Context));
+     if (h->DPB && !h->avctx->internal->is_copy) {
+         for (i = 0; i < h->picture_count; i++) {
+             free_picture(h, &h->DPB[i]);
+         }
+     }
+     av_freep(&h->DPB);
  
      return 0;
  }
@@@ -594,17 -620,11 +636,19 @@@ typedef struct H264Context 
  
      int cur_chroma_format_idc;
      uint8_t *bipred_scratchpad;
 +
 +    int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low
 +
 +    int sync;                      ///< did we had a keyframe or recovery point
 +
 +    uint8_t parse_history[4];
 +    int parse_history_count;
 +    int parse_last_mb;
+     uint8_t *edge_emu_buffer;
+     int16_t *dc_val_base;
  } H264Context;
  
 -extern const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM + 1]; ///< One chroma qp table for each supported bit depth (8, 9, 10).
 +extern const uint8_t ff_h264_chroma_qp[7][QP_MAX_NUM + 1]; ///< One chroma qp table for each possible bit depth (8-14).
  extern const uint16_t ff_h264_mb_sizes[4];
  
  /**
@@@ -1884,11 -1880,10 +1879,11 @@@ int ff_h264_decode_mb_cabac(H264Contex
      int dct8x8_allowed= h->pps.transform_8x8_mode;
      int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;
      const int pixel_shift = h->pixel_shift;
 +    unsigned local_ref_count[2];
  
-     mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride;
+     mb_xy = h->mb_xy = h->mb_x + h->mb_y*h->mb_stride;
  
-     tprintf(s->avctx, "pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y);
+     tprintf(h->avctx, "pic:%d mb:%d/%d\n", h->frame_num, h->mb_x, h->mb_y);
      if( h->slice_type_nos != AV_PICTURE_TYPE_I ) {
          int skip;
          /* a skipped mb needs the aff flag from the following mb */
@@@ -2096,10 -2088,11 +2091,10 @@@ decode_intra_mb
                  for( i = 0; i < 4; i++ ) {
                      if(IS_DIRECT(h->sub_mb_type[i])) continue;
                      if(IS_DIR(h->sub_mb_type[i], 0, list)){
 -                        int rc = h->ref_count[list] << MB_MBAFF;
 -                        if (rc > 1) {
 +                        if (local_ref_count[list] > 1) {
                              ref[list][i] = decode_cabac_mb_ref( h, list, 4*i );
 -                            if (ref[list][i] >= (unsigned) rc) {
 -                                av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], rc);
 +                            if (ref[list][i] >= (unsigned)local_ref_count[list]) {
-                                 av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], local_ref_count[list]);
++                                av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], local_ref_count[list]);
                                  return -1;
                              }
                          }else
          if(IS_16X16(mb_type)){
              for(list=0; list<h->list_count; list++){
                  if(IS_DIR(mb_type, 0, list)){
 -                    int ref, rc = h->ref_count[list] << MB_MBAFF;
 -                    if (rc > 1) {
 +                    int ref;
 +                    if (local_ref_count[list] > 1) {
                          ref= decode_cabac_mb_ref(h, list, 0);
 -                        if (ref >= (unsigned) rc) {
 -                            av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
 +                        if (ref >= (unsigned)local_ref_count[list]) {
-                             av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
++                            av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
                              return -1;
                          }
                      }else
              for(list=0; list<h->list_count; list++){
                      for(i=0; i<2; i++){
                          if(IS_DIR(mb_type, i, list)){
 -                            int ref, rc = h->ref_count[list] << MB_MBAFF;
 -                            if (rc > 1) {
 +                            int ref;
 +                            if (local_ref_count[list] > 1) {
                                  ref= decode_cabac_mb_ref( h, list, 8*i );
 -                                if (ref >= (unsigned) rc) {
 -                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
 +                                if (ref >= (unsigned)local_ref_count[list]) {
-                                     av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
++                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
                                      return -1;
                                  }
                              }else
              for(list=0; list<h->list_count; list++){
                      for(i=0; i<2; i++){
                          if(IS_DIR(mb_type, i, list)){ //FIXME optimize
 -                            int ref, rc = h->ref_count[list] << MB_MBAFF;
 -                            if (rc > 1) {
 +                            int ref;
 +                            if (local_ref_count[list] > 1) {
                                  ref= decode_cabac_mb_ref( h, list, 4*i );
 -                                if (ref >= (unsigned) rc) {
 -                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
 +                                if (ref >= (unsigned)local_ref_count[list]) {
-                                     av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
++                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
                                      return -1;
                                  }
                              }else
          cbp  = decode_cabac_mb_cbp_luma( h );
          if(decode_chroma)
              cbp |= decode_cabac_mb_cbp_chroma( h ) << 4;
-             av_log(s->avctx, AV_LOG_ERROR, "gray chroma\n");
 +    } else {
 +        if (!decode_chroma && cbp>15) {
++            av_log(h->avctx, AV_LOG_ERROR, "gray chroma\n");
 +            return AVERROR_INVALIDDATA;
 +        }
      }
  
      h->cbp_table[mb_xy] = h->cbp = cbp;
@@@ -479,8 -478,8 +478,8 @@@ static int decode_residual(H264Context 
      }
  
      trailing_ones= coeff_token&3;
-     tprintf(h->s.avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff);
+     tprintf(h->avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff);
 -    assert(total_coeff<=16);
 +    av_assert2(total_coeff<=16);
  
      i = show_bits(gb, 3);
      skip_bits(gb, trailing_ones);
                  else
                      level_code= prefix + get_bits(gb, 4); //part
              }else{
 -                level_code= 30 + get_bits(gb, prefix-3); //part
 +                level_code= 30;
                  if(prefix>=16){
                      if(prefix > 25+3){
-                         av_log(h->s.avctx, AV_LOG_ERROR, "Invalid level prefix\n");
+                         av_log(h->avctx, AV_LOG_ERROR, "Invalid level prefix\n");
                          return -1;
                      }
                      level_code += (1<<(prefix-3))-4096;
          STORE_BLOCK(int16_t)
      }
  
-         av_log(h->s.avctx, AV_LOG_ERROR, "negative number of zero coeffs at %d %d\n", s->mb_x, s->mb_y);
 +    if(zeros_left<0){
++        av_log(h->avctx, AV_LOG_ERROR, "negative number of zero coeffs at %d %d\n", h->mb_x, h->mb_y);
 +        return -1;
 +    }
 +
      return 0;
  }
  
@@@ -700,11 -697,10 +697,11 @@@ int ff_h264_decode_mb_cavlc(H264Contex
      int dct8x8_allowed= h->pps.transform_8x8_mode;
      int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;
      const int pixel_shift = h->pixel_shift;
 +    unsigned local_ref_count[2];
  
-     mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride;
+     mb_xy = h->mb_xy = h->mb_x + h->mb_y*h->mb_stride;
  
-     tprintf(s->avctx, "pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y);
+     tprintf(h->avctx, "pic:%d mb:%d/%d\n", h->frame_num, h->mb_x, h->mb_y);
      cbp = 0; /* avoid warning. FIXME: find a solution without slowing
                  down the code */
      if(h->slice_type_nos != AV_PICTURE_TYPE_I){
@@@ -855,11 -848,11 +852,11 @@@ decode_intra_mb
                  h->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;
              }
          }else{
 -            assert(h->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ?
 +            av_assert2(h->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ?
              for(i=0; i<4; i++){
-                 h->sub_mb_type[i]= get_ue_golomb_31(&s->gb);
+                 h->sub_mb_type[i]= get_ue_golomb_31(&h->gb);
                  if(h->sub_mb_type[i] >=4){
-                     av_log(h->s.avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], s->mb_x, s->mb_y);
+                     av_log(h->avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], h->mb_x, h->mb_y);
                      return -1;
                  }
                  sub_partition_count[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;
              for(list=0; list<h->list_count; list++){
                      unsigned int val;
                      if(IS_DIR(mb_type, 0, list)){
 -                        int rc = h->ref_count[list] << MB_MBAFF;
 -                        if (rc == 1) {
 +                        if(local_ref_count[list]==1){
                              val= 0;
 -                        } else if (rc == 2) {
 +                        }else if(local_ref_count[list]==2){
-                             val= get_bits1(&s->gb)^1;
+                             val= get_bits1(&h->gb)^1;
                          }else{
-                             val= get_ue_golomb_31(&s->gb);
+                             val= get_ue_golomb_31(&h->gb);
 -                            if (val >= rc) {
 +                            if(val >= local_ref_count[list]){
-                                 av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
+                                 av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                  return -1;
                              }
                          }
                      for(i=0; i<2; i++){
                          unsigned int val;
                          if(IS_DIR(mb_type, i, list)){
 -                            int rc = h->ref_count[list] << MB_MBAFF;
 -                            if (rc == 1) {
 +                            if(local_ref_count[list] == 1){
                                  val= 0;
 -                            } else if (rc == 2) {
 +                            }else if(local_ref_count[list] == 2){
-                                 val= get_bits1(&s->gb)^1;
+                                 val= get_bits1(&h->gb)^1;
                              }else{
-                                 val= get_ue_golomb_31(&s->gb);
+                                 val= get_ue_golomb_31(&h->gb);
 -                                if (val >= rc) {
 +                                if(val >= local_ref_count[list]){
-                                     av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
+                                     av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                      return -1;
                                  }
                              }
                      for(i=0; i<2; i++){
                          unsigned int val;
                          if(IS_DIR(mb_type, i, list)){ //FIXME optimize
 -                            int rc = h->ref_count[list] << MB_MBAFF;
 -                            if (rc == 1) {
 +                            if(local_ref_count[list]==1){
                                  val= 0;
 -                            } else if (rc == 2) {
 +                            }else if(local_ref_count[list]==2){
-                                 val= get_bits1(&s->gb)^1;
+                                 val= get_bits1(&h->gb)^1;
                              }else{
-                                 val= get_ue_golomb_31(&s->gb);
+                                 val= get_ue_golomb_31(&h->gb);
 -                                if (val >= rc) {
 +                                if(val >= local_ref_count[list]){
-                                     av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
+                                     av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                      return -1;
                                  }
                              }
              if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp_gray[cbp];
              else                     cbp= golomb_to_inter_cbp_gray[cbp];
          }
-             av_log(s->avctx, AV_LOG_ERROR, "gray chroma\n");
 +    } else {
 +        if (!decode_chroma && cbp>15) {
++            av_log(h->avctx, AV_LOG_ERROR, "gray chroma\n");
 +            return AVERROR_INVALIDDATA;
 +        }
      }
  
      if(dct8x8_allowed && (cbp&15) && !IS_INTRA(mb_type)){
Simple merge
@@@ -241,8 -244,7 +241,7 @@@ static av_always_inline void h264_filte
                                                            unsigned int uvlinesize,
                                                            int pixel_shift)
  {
-     MpegEncContext * const s = &h->s;
-     int chroma = CHROMA && !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
 -    int chroma = !(CONFIG_GRAY && (h->flags&CODEC_FLAG_GRAY));
++    int chroma = CHROMA && !(CONFIG_GRAY && (h->flags&CODEC_FLAG_GRAY));
      int chroma444 = CHROMA444;
      int chroma422 = CHROMA422;
  
@@@ -579,12 -580,10 +577,12 @@@ static av_always_inline void filter_mb_
              // Do not use s->qscale as luma quantizer because it has not the same
              // value in IPCM macroblocks.
              if(bS[0]+bS[1]+bS[2]+bS[3]){
-                 qp = (s->current_picture.f.qscale_table[mb_xy] + s->current_picture.f.qscale_table[mbm_xy] + 1) >> 1;
-                 //tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], s->current_picture.qscale_table[mbn_xy]);
-                 tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
-                 //{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
-                 chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, s->current_picture.f.qscale_table[mbm_xy]) + 1) >> 1;
-                 chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, s->current_picture.f.qscale_table[mbm_xy]) + 1) >> 1;
+                 qp = (h->cur_pic.f.qscale_table[mb_xy] + h->cur_pic.f.qscale_table[mbm_xy] + 1) >> 1;
++                //tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], h->cur_pic.qscale_table[mbn_xy]);
+                 tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
++                //{ int i; for (i = 0; i < 4; i++) tprintf(h->avctx, " bS[%d]:%d", i, bS[i]); tprintf(h->avctx, "\n"); }
+                 chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.f.qscale_table[mbm_xy]) + 1) >> 1;
+                 chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.f.qscale_table[mbm_xy]) + 1) >> 1;
                  if( dir == 0 ) {
                      filter_mb_edgev( &img_y[0], linesize, bS, qp, a, b, h, 1 );
                      if (chroma) {
          /* Filter edge */
          // Do not use s->qscale as luma quantizer because it has not the same
          // value in IPCM macroblocks.
-         qp = s->current_picture.f.qscale_table[mb_xy];
-         //tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], s->current_picture.qscale_table[mbn_xy]);
-         tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
-         //{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
+         qp = h->cur_pic.f.qscale_table[mb_xy];
++        //tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], h->cur_pic.qscale_table[mbn_xy]);
+         tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
++        //{ int i; for (i = 0; i < 4; i++) tprintf(h->avctx, " bS[%d]:%d", i, bS[i]); tprintf(h->avctx, "\n"); }
          if( dir == 0 ) {
              filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, a, b, h, 0 );
              if (chroma) {
@@@ -710,7 -706,7 +707,7 @@@ void ff_h264_filter_mb( H264Context *h
      const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4;
      int first_vertical_edge_done = 0;
      av_unused int dir;
-     int chroma = CHROMA && !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
 -    int chroma = !(CONFIG_GRAY && (h->flags&CODEC_FLAG_GRAY));
++    int chroma = CHROMA && !(CONFIG_GRAY && (h->flags&CODEC_FLAG_GRAY));
      int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);
      int a = h->slice_alpha_c0_offset - qp_bd_offset;
      int b = h->slice_beta_offset - qp_bd_offset;
@@@ -136,11 -138,11 +135,11 @@@ static av_noinline void FUNC(hl_decode_
          } else {
              for (i = 0; i < 16; i++)
                  memcpy(dest_y + i * linesize, (uint8_t *)h->mb + i * 16, 16);
-             if (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+             if (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
                  if (!h->sps.chroma_format_idc) {
 -                    for (i = 0; i < block_h; i++) {
 -                        memset(dest_cb + i * uvlinesize, 128, 8);
 -                        memset(dest_cr + i * uvlinesize, 128, 8);
 +                    for (i = 0; i < 8; i++) {
 +                        memset(dest_cb + i*uvlinesize, 1 << (bit_depth - 1), 8);
 +                        memset(dest_cr + i*uvlinesize, 1 << (bit_depth - 1), 8);
                      }
                  } else {
                      uint8_t *src_cb = (uint8_t *)h->mb + 256;
@@@ -67,13 -67,12 +67,12 @@@ static void MCFUNC(hl_motion)(H264Conte
                                h264_weight_func *weight_op,
                                h264_biweight_func *weight_avg)
  {
-     MpegEncContext *const s = &h->s;
      const int mb_xy   = h->mb_xy;
-     const int mb_type = s->current_picture.f.mb_type[mb_xy];
+     const int mb_type = h->cur_pic.f.mb_type[mb_xy];
  
 -    assert(IS_INTER(mb_type));
 +    av_assert2(IS_INTER(mb_type));
  
-     if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
+     if (HAVE_THREADS && (h->avctx->active_thread_type & FF_THREAD_FRAME))
          await_references(h);
      prefetch_motion(h, 0, PIXEL_SHIFT, CHROMA_IDC);
  
@@@ -483,9 -480,9 +479,9 @@@ static void fill_decode_caches(H264Cont
                          h->left_samples_available    &= 0xFF5F;
                      }
                  } else {
-                     int left_typei = s->current_picture.f.mb_type[left_xy[LTOP] + s->mb_stride];
+                     int left_typei = h->cur_pic.f.mb_type[left_xy[LTOP] + h->mb_stride];
  
 -                    assert(left_xy[LTOP] == left_xy[LBOT]);
 +                    av_assert2(left_xy[LTOP] == left_xy[LBOT]);
                      if (!((left_typei & type_mask) && (left_type[LTOP] & type_mask))) {
                          h->topleft_samples_available &= 0xDF5F;
                          h->left_samples_available    &= 0x5F5F;
          int b_stride = h->b_stride;
          for (list = 0; list < h->list_count; list++) {
              int8_t *ref_cache = &h->ref_cache[list][scan8[0]];
-             int8_t *ref       = s->current_picture.f.ref_index[list];
+             int8_t *ref       = h->cur_pic.f.ref_index[list];
              int16_t(*mv_cache)[2] = &h->mv_cache[list][scan8[0]];
-             int16_t(*mv)[2]       = s->current_picture.f.motion_val[list];
+             int16_t(*mv)[2]       = h->cur_pic.f.motion_val[list];
              if (!USES_LIST(mb_type, list))
                  continue;
 -            assert(!(IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred));
 +            av_assert2(!(IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred));
  
              if (USES_LIST(top_type, list)) {
                  const int b_xy = h->mb2b_xy[top_xy] + 3 * b_stride;
  
  static int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size)
  {
 -    int i;
 +    int i, j;
      uint32_t state;
-     ParseContext *pc = &(h->s.parse_context);
+     ParseContext *pc = &h->parse_context;
 +    int next_avc= h->is_avc ? 0 : buf_size;
 +
  //    mb_addr= pc->mb_addr - 1;
      state= pc->state;
      if(state>13)
          state= 7;
  
-         av_log(h->s.avctx, AV_LOG_ERROR, "AVC-parser: nal length size invalid\n");
 +    if(h->is_avc && !h->nal_length_size)
++        av_log(h->avctx, AV_LOG_ERROR, "AVC-parser: nal length size invalid\n");
 +
      for(i=0; i<buf_size; i++){
-                 av_log(h->s.avctx, AV_LOG_ERROR, "AVC-parser: nal size %d remaining %d\n", nalsize, buf_size - i);
 +        if(i >= next_avc) {
 +            int nalsize = 0;
 +            i = next_avc;
 +            for(j = 0; j < h->nal_length_size; j++)
 +                nalsize = (nalsize << 8) | buf[i++];
 +            if(nalsize <= 0 || nalsize > buf_size - i){
++                av_log(h->avctx, AV_LOG_ERROR, "AVC-parser: nal size %d remaining %d\n", nalsize, buf_size - i);
 +                return buf_size;
 +            }
 +            next_avc= i + nalsize;
 +            state= 5;
 +        }
 +
          if(state==7){
  #if HAVE_FAST_UNALIGNED
          /* we check i<buf_size instead of i+3/7 because its simpler
@@@ -163,19 -129,7 +163,19 @@@ static inline int parse_nal_units(AVCod
          return 0;
  
      for(;;) {
 -        int src_length, dst_length, consumed;
 +        int src_length, dst_length, consumed, nalsize = 0;
 +        if (h->is_avc) {
 +            int i;
 +            if (h->nal_length_size >= buf_end - buf) break;
 +            nalsize = 0;
 +            for (i = 0; i < h->nal_length_size; i++)
 +                nalsize = (nalsize << 8) | *buf++;
 +            if (nalsize <= 0 || nalsize > buf_end - buf) {
-                 av_log(h->s.avctx, AV_LOG_ERROR, "AVC: nal size %d\n", nalsize);
++                av_log(h->avctx, AV_LOG_ERROR, "AVC: nal size %d\n", nalsize);
 +                break;
 +            }
 +            src_length = nalsize;
 +        } else {
          buf = avpriv_mpv_find_start_code(buf, buf_end, &state);
          if(buf >= buf_end)
              break;
              s->key_frame = 1;
              /* fall through */
          case NAL_SLICE:
-             get_ue_golomb_long(&h->s.gb);  // skip first_mb_in_slice
-             slice_type = get_ue_golomb_31(&h->s.gb);
 -            get_ue_golomb(&h->gb);  // skip first_mb_in_slice
++            get_ue_golomb_long(&h->gb);  // skip first_mb_in_slice
+             slice_type = get_ue_golomb_31(&h->gb);
              s->pict_type = golomb_to_pict_type[slice_type % 5];
              if (h->sei_recovery_frame_cnt >= 0) {
                  /* key frame, since recovery_frame_cnt is set */
  
              return 0; /* no need to evaluate the rest */
          }
 -        buf += consumed;
 +        buf += h->is_avc ? nalsize : consumed;
      }
 +    if (q264)
 +        return 0;
      /* didn't find a picture! */
-     av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit with size %d\n", buf_size);
 -    av_log(h->avctx, AV_LOG_ERROR, "missing picture in access unit\n");
++    av_log(h->avctx, AV_LOG_ERROR, "missing picture in access unit with size %d\n", buf_size);
      return -1;
  }
  
@@@ -298,14 -249,15 +298,14 @@@ static int h264_parse(AVCodecParserCont
      if (!h->got_first) {
          h->got_first = 1;
          if (avctx->extradata_size) {
-             h->s.avctx = avctx;
+             h->avctx = avctx;
 -            // must be done like in the decoder.
 -            // otherwise opening the parser, creating extradata,
 -            // and then closing and opening again
 +            // must be done like in decoder, otherwise opening the parser,
 +            // letting it create extradata and then closing and opening again
              // will cause has_b_frames to be always set.
 -            // NB: estimate_timings_from_pts behaves exactly like this.
 +            // Note that estimate_timings_from_pts does exactly this.
              if (!avctx->has_b_frames)
-                 h->s.low_delay = 1;
+                 h->low_delay = 1;
 -            ff_h264_decode_extradata(h);
 +            ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size);
          }
      }
  
@@@ -247,21 -215,20 +245,21 @@@ static inline int decode_vui_parameters
          if(decode_hrd_parameters(h, sps) < 0)
              return -1;
      if(sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag)
-         get_bits1(&s->gb);     /* low_delay_hrd_flag */
-     sps->pic_struct_present_flag = get_bits1(&s->gb);
-     if(!get_bits_left(&s->gb))
+         get_bits1(&h->gb);     /* low_delay_hrd_flag */
+     sps->pic_struct_present_flag = get_bits1(&h->gb);
 -
++    if(!get_bits_left(&h->gb))
 +        return 0;
-     sps->bitstream_restriction_flag = get_bits1(&s->gb);
+     sps->bitstream_restriction_flag = get_bits1(&h->gb);
      if(sps->bitstream_restriction_flag){
-         get_bits1(&s->gb);     /* motion_vectors_over_pic_boundaries_flag */
-         get_ue_golomb(&s->gb); /* max_bytes_per_pic_denom */
-         get_ue_golomb(&s->gb); /* max_bits_per_mb_denom */
-         get_ue_golomb(&s->gb); /* log2_max_mv_length_horizontal */
-         get_ue_golomb(&s->gb); /* log2_max_mv_length_vertical */
-         sps->num_reorder_frames= get_ue_golomb(&s->gb);
-         get_ue_golomb(&s->gb); /*max_dec_frame_buffering*/
-         if (get_bits_left(&s->gb) < 0) {
+         get_bits1(&h->gb);     /* motion_vectors_over_pic_boundaries_flag */
+         get_ue_golomb(&h->gb); /* max_bytes_per_pic_denom */
+         get_ue_golomb(&h->gb); /* max_bits_per_mb_denom */
+         get_ue_golomb(&h->gb); /* log2_max_mv_length_horizontal */
+         get_ue_golomb(&h->gb); /* log2_max_mv_length_vertical */
+         sps->num_reorder_frames= get_ue_golomb(&h->gb);
+         get_ue_golomb(&h->gb); /*max_dec_frame_buffering*/
+         if (get_bits_left(&h->gb) < 0) {
              sps->num_reorder_frames=0;
              sps->bitstream_restriction_flag= 0;
          }
              return -1;
          }
      }
-     if (get_bits_left(&s->gb) < 0) {
-         av_log(h->s.avctx, AV_LOG_ERROR, "Overread VUI by %d bits\n", -get_bits_left(&s->gb));
 +
+     if (get_bits_left(&h->gb) < 0) {
+         av_log(h->avctx, AV_LOG_ERROR, "Overread VUI by %d bits\n", -get_bits_left(&h->gb));
          return AVERROR_INVALIDDATA;
      }
  
@@@ -337,19 -302,17 +332,19 @@@ int ff_h264_decode_seq_parameter_set(H2
      int i, log2_max_frame_num_minus4;
      SPS *sps;
  
-     profile_idc= get_bits(&s->gb, 8);
-     constraint_set_flags |= get_bits1(&s->gb) << 0;   //constraint_set0_flag
-     constraint_set_flags |= get_bits1(&s->gb) << 1;   //constraint_set1_flag
-     constraint_set_flags |= get_bits1(&s->gb) << 2;   //constraint_set2_flag
-     constraint_set_flags |= get_bits1(&s->gb) << 3;   //constraint_set3_flag
-     constraint_set_flags |= get_bits1(&s->gb) << 4;   //constraint_set4_flag
-     constraint_set_flags |= get_bits1(&s->gb) << 5;   //constraint_set5_flag
-     get_bits(&s->gb, 2); // reserved
-     level_idc= get_bits(&s->gb, 8);
-     sps_id= get_ue_golomb_31(&s->gb);
+     profile_idc= get_bits(&h->gb, 8);
+     constraint_set_flags |= get_bits1(&h->gb) << 0;   //constraint_set0_flag
+     constraint_set_flags |= get_bits1(&h->gb) << 1;   //constraint_set1_flag
+     constraint_set_flags |= get_bits1(&h->gb) << 2;   //constraint_set2_flag
+     constraint_set_flags |= get_bits1(&h->gb) << 3;   //constraint_set3_flag
 -    get_bits(&h->gb, 4); // reserved
++    constraint_set_flags |= get_bits1(&h->gb) << 4;   //constraint_set4_flag
++    constraint_set_flags |= get_bits1(&h->gb) << 5;   //constraint_set5_flag
++    get_bits(&h->gb, 2); // reserved
+     level_idc= get_bits(&h->gb, 8);
+     sps_id= get_ue_golomb_31(&h->gb);
  
      if(sps_id >= MAX_SPS_COUNT) {
-         av_log(h->s.avctx, AV_LOG_ERROR, "sps_id (%d) out of range\n", sps_id);
+         av_log(h->avctx, AV_LOG_ERROR, "sps_id (%d) out of range\n", sps_id);
          return -1;
      }
      sps= av_mallocz(sizeof(SPS));
          sps->profile_idc ==  44 || sps->profile_idc ==  83 ||
          sps->profile_idc ==  86 || sps->profile_idc == 118 ||
          sps->profile_idc == 128 || sps->profile_idc == 144) {
-         sps->chroma_format_idc= get_ue_golomb_31(&s->gb);
+         sps->chroma_format_idc= get_ue_golomb_31(&h->gb);
 -        if(sps->chroma_format_idc > 3) {
 -            av_log(h->avctx, AV_LOG_ERROR, "chroma_format_idc (%u) out of range\n", sps->chroma_format_idc);
 +        if (sps->chroma_format_idc > 3U) {
-             av_log(h->s.avctx, AV_LOG_ERROR, "chroma_format_idc %d is illegal\n", sps->chroma_format_idc);
++            av_log(h->avctx, AV_LOG_ERROR, "chroma_format_idc %d is illegal\n", sps->chroma_format_idc);
              goto fail;
          } else if(sps->chroma_format_idc == 3) {
-             sps->residual_color_transform_flag = get_bits1(&s->gb);
+             sps->residual_color_transform_flag = get_bits1(&h->gb);
 +            if(sps->residual_color_transform_flag) {
-                 av_log(h->s.avctx, AV_LOG_ERROR, "separate color planes are not supported\n");
++                av_log(h->avctx, AV_LOG_ERROR, "separate color planes are not supported\n");
 +                goto fail;
 +            }
          }
-         sps->bit_depth_luma   = get_ue_golomb(&s->gb) + 8;
-         sps->bit_depth_chroma = get_ue_golomb(&s->gb) + 8;
+         sps->bit_depth_luma   = get_ue_golomb(&h->gb) + 8;
+         sps->bit_depth_chroma = get_ue_golomb(&h->gb) + 8;
 +        if (sps->bit_depth_luma > 14U || sps->bit_depth_chroma > 14U) {
-             av_log(h->s.avctx, AV_LOG_ERROR, "illegal bit depth value (%d, %d)\n",
++            av_log(h->avctx, AV_LOG_ERROR, "illegal bit depth value (%d, %d)\n",
 +                   sps->bit_depth_luma, sps->bit_depth_chroma);
 +            goto fail;
 +        }
-         sps->transform_bypass = get_bits1(&s->gb);
+         sps->transform_bypass = get_bits1(&h->gb);
          decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8);
      }else{
          sps->chroma_format_idc= 1;
      }
      sps->log2_max_frame_num = log2_max_frame_num_minus4 + 4;
  
-     sps->poc_type= get_ue_golomb_31(&s->gb);
+     sps->poc_type= get_ue_golomb_31(&h->gb);
  
      if(sps->poc_type == 0){ //FIXME #define
-         unsigned t = get_ue_golomb(&s->gb);
 -        sps->log2_max_poc_lsb= get_ue_golomb(&h->gb) + 4;
++        unsigned t = get_ue_golomb(&h->gb);
 +        if(t>12){
-             av_log(h->s.avctx, AV_LOG_ERROR, "log2_max_poc_lsb (%d) is out of range\n", t);
++            av_log(h->avctx, AV_LOG_ERROR, "log2_max_poc_lsb (%d) is out of range\n", t);
 +            goto fail;
 +        }
 +        sps->log2_max_poc_lsb= t + 4;
      } else if(sps->poc_type == 1){//FIXME #define
-         sps->delta_pic_order_always_zero_flag= get_bits1(&s->gb);
-         sps->offset_for_non_ref_pic= get_se_golomb(&s->gb);
-         sps->offset_for_top_to_bottom_field= get_se_golomb(&s->gb);
-         sps->poc_cycle_length                = get_ue_golomb(&s->gb);
+         sps->delta_pic_order_always_zero_flag= get_bits1(&h->gb);
+         sps->offset_for_non_ref_pic= get_se_golomb(&h->gb);
+         sps->offset_for_top_to_bottom_field= get_se_golomb(&h->gb);
+         sps->poc_cycle_length                = get_ue_golomb(&h->gb);
  
          if((unsigned)sps->poc_cycle_length >= FF_ARRAY_ELEMS(sps->offset_for_ref_frame)){
-             av_log(h->s.avctx, AV_LOG_ERROR, "poc_cycle_length overflow %u\n", sps->poc_cycle_length);
+             av_log(h->avctx, AV_LOG_ERROR, "poc_cycle_length overflow %u\n", sps->poc_cycle_length);
              goto fail;
          }
  
          goto fail;
      }
  
-     sps->ref_frame_count= get_ue_golomb_31(&s->gb);
-     if (h->s.avctx->codec_tag == MKTAG('S', 'M', 'V', '2'))
+     sps->ref_frame_count= get_ue_golomb_31(&h->gb);
 -    if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count >= 32U){
++    if (h->avctx->codec_tag == MKTAG('S', 'M', 'V', '2'))
 +        sps->ref_frame_count= FFMAX(2, sps->ref_frame_count);
 +    if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count > 16U){
-         av_log(h->s.avctx, AV_LOG_ERROR, "too many reference frames\n");
+         av_log(h->avctx, AV_LOG_ERROR, "too many reference frames\n");
          goto fail;
      }
-     sps->gaps_in_frame_num_allowed_flag= get_bits1(&s->gb);
-     sps->mb_width = get_ue_golomb(&s->gb) + 1;
-     sps->mb_height= get_ue_golomb(&s->gb) + 1;
+     sps->gaps_in_frame_num_allowed_flag= get_bits1(&h->gb);
+     sps->mb_width = get_ue_golomb(&h->gb) + 1;
+     sps->mb_height= get_ue_golomb(&h->gb) + 1;
      if((unsigned)sps->mb_width >= INT_MAX/16 || (unsigned)sps->mb_height >= INT_MAX/16 ||
-        av_image_check_size(16*sps->mb_width, 16*sps->mb_height, 0, h->s.avctx)){
-         av_log(h->s.avctx, AV_LOG_ERROR, "mb_width/height overflow\n");
+        av_image_check_size(16*sps->mb_width, 16*sps->mb_height, 0, h->avctx)){
+         av_log(h->avctx, AV_LOG_ERROR, "mb_width/height overflow\n");
          goto fail;
      }
  
      else
          sps->mb_aff= 0;
  
-     sps->direct_8x8_inference_flag= get_bits1(&s->gb);
+     sps->direct_8x8_inference_flag= get_bits1(&h->gb);
 -    if(!sps->frame_mbs_only_flag && !sps->direct_8x8_inference_flag){
 -        av_log(h->avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n");
 -        goto fail;
 -    }
  
  #ifndef ALLOW_INTERLACE
      if(sps->mb_aff)
              sps->crop_bottom = 0;
          }
          if(sps->crop_left || sps->crop_top){
-             av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ... (left: %d, top: %d)\n", sps->crop_left, sps->crop_top);
 -            av_log(h->avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n");
++            av_log(h->avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ... (left: %d, top: %d)\n", sps->crop_left, sps->crop_top);
          }
          if(sps->crop_right >= crop_horizontal_limit || sps->crop_bottom >= crop_vertical_limit){
-             av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, cropping disabled (right: %d, bottom: %d)\n", sps->crop_right, sps->crop_bottom);
 -            av_log(h->avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n");
++            av_log(h->avctx, AV_LOG_ERROR, "brainfart cropping not supported, cropping disabled (right: %d, bottom: %d)\n", sps->crop_right, sps->crop_bottom);
 +        /* It is very unlikely that partial cropping will make anybody happy.
 +         * Not cropping at all fixes for example playback of Sisvel 3D streams
 +         * in applications supporting Sisvel 3D. */
 +        sps->crop_left  =
 +        sps->crop_right =
 +        sps->crop_top   =
 +        sps->crop_bottom= 0;
          }
      }else{
          sps->crop_left  =
      if(!sps->sar.den)
          sps->sar.den= 1;
  
-     if(s->avctx->debug&FF_DEBUG_PICT_INFO){
+     if(h->avctx->debug&FF_DEBUG_PICT_INFO){
          static const char csp[4][5] = { "Gray", "420", "422", "444" };
-         av_log(h->s.avctx, AV_LOG_DEBUG, "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %s %d/%d b%d reo:%d\n",
 -        av_log(h->avctx, AV_LOG_DEBUG, "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %s %d/%d\n",
++        av_log(h->avctx, AV_LOG_DEBUG, "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %s %d/%d b%d reo:%d\n",
                 sps_id, sps->profile_idc, sps->level_idc,
                 sps->poc_type,
                 sps->ref_frame_count,
@@@ -554,36 -494,17 +549,35 @@@ build_qp_table(PPS *pps, int t, int ind
          pps->chroma_qp_table[t][i] = ff_h264_chroma_qp[depth-8][av_clip(i + index, 0, max_qp)];
  }
  
-         av_log(h->s.avctx, AV_LOG_VERBOSE,
 +static int more_rbsp_data_in_pps(H264Context *h, PPS *pps)
 +{
 +    const SPS *sps = h->sps_buffers[pps->sps_id];
 +    int profile_idc = sps->profile_idc;
 +
 +    if ((profile_idc == 66 || profile_idc == 77 ||
 +         profile_idc == 88) && (sps->constraint_set_flags & 7)) {
++        av_log(h->avctx, AV_LOG_VERBOSE,
 +               "Current profile doesn't provide more RBSP data in PPS, skipping\n");
 +        return 0;
 +    }
 +
 +    return 1;
 +}
 +
  int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){
-     MpegEncContext * const s = &h->s;
-     unsigned int pps_id= get_ue_golomb(&s->gb);
+     unsigned int pps_id= get_ue_golomb(&h->gb);
      PPS *pps;
      const int qp_bd_offset = 6*(h->sps.bit_depth_luma-8);
      int bits_left;
  
      if(pps_id >= MAX_PPS_COUNT) {
-         av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id);
+         av_log(h->avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id);
          return -1;
 -    } else if (h->sps.bit_depth_luma > 10) {
 -        av_log(h->avctx, AV_LOG_ERROR, "Unimplemented luma bit depth=%d (max=10)\n", h->sps.bit_depth_luma);
 +    } else if (h->sps.bit_depth_luma > 14) {
-         av_log(h->s.avctx, AV_LOG_ERROR, "Invalid luma bit depth=%d\n", h->sps.bit_depth_luma);
++        av_log(h->avctx, AV_LOG_ERROR, "Invalid luma bit depth=%d\n", h->sps.bit_depth_luma);
 +        return AVERROR_INVALIDDATA;
 +    } else if (h->sps.bit_depth_luma == 11 || h->sps.bit_depth_luma == 13) {
-         av_log(h->s.avctx, AV_LOG_ERROR, "Unimplemented luma bit depth=%d\n", h->sps.bit_depth_luma);
++        av_log(h->avctx, AV_LOG_ERROR, "Unimplemented luma bit depth=%d\n", h->sps.bit_depth_luma);
          return AVERROR_PATCHWELCOME;
      }
  
      memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4, sizeof(pps->scaling_matrix4));
      memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8, sizeof(pps->scaling_matrix8));
  
-     bits_left = bit_length - get_bits_count(&s->gb);
+     bits_left = bit_length - get_bits_count(&h->gb);
 -    if (bits_left && (bits_left > 8 ||
 -                      show_bits(&h->gb, bits_left) != 1 << (bits_left - 1))) {
 +    if(bits_left > 0 && more_rbsp_data_in_pps(h, pps)){
-         pps->transform_8x8_mode= get_bits1(&s->gb);
+         pps->transform_8x8_mode= get_bits1(&h->gb);
          decode_scaling_matrices(h, h->sps_buffers[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8);
-         pps->chroma_qp_index_offset[1]= get_se_golomb(&s->gb); //second_chroma_qp_index_offset
+         pps->chroma_qp_index_offset[1]= get_se_golomb(&h->gb); //second_chroma_qp_index_offset
      } else {
          pps->chroma_qp_index_offset[1]= pps->chroma_qp_index_offset[0];
      }
@@@ -123,10 -121,10 +122,10 @@@ int ff_h264_fill_default_ref_list(H264C
          for(list= 0; list<2; list++){
              len= add_sorted(sorted    , h->short_ref, h->short_ref_count, cur_poc, 1^list);
              len+=add_sorted(sorted+len, h->short_ref, h->short_ref_count, cur_poc, 0^list);
 -            assert(len<=32);
 +            av_assert0(len<=32);
-             len= build_def_list(h->default_ref_list[list]    , sorted     , len, 0, s->picture_structure);
-             len+=build_def_list(h->default_ref_list[list]+len, h->long_ref, 16 , 1, s->picture_structure);
+             len= build_def_list(h->default_ref_list[list]    , sorted     , len, 0, h->picture_structure);
+             len+=build_def_list(h->default_ref_list[list]+len, h->long_ref, 16 , 1, h->picture_structure);
 -            assert(len<=32);
 +            av_assert0(len<=32);
  
              if(len < h->ref_count[list])
                  memset(&h->default_ref_list[list][len], 0, sizeof(Picture)*(h->ref_count[list] - len));
                  FFSWAP(Picture, h->default_ref_list[1][0], h->default_ref_list[1][1]);
          }
      }else{
-         len = build_def_list(h->default_ref_list[0]    , h->short_ref, h->short_ref_count, 0, s->picture_structure);
-         len+= build_def_list(h->default_ref_list[0]+len, h-> long_ref, 16                , 1, s->picture_structure);
+         len = build_def_list(h->default_ref_list[0]    , h->short_ref, h->short_ref_count, 0, h->picture_structure);
+         len+= build_def_list(h->default_ref_list[0]+len, h-> long_ref, 16                , 1, h->picture_structure);
 -        assert(len <= 32);
 +        av_assert0(len<=32);
          if(len < h->ref_count[0])
              memset(&h->default_ref_list[0][len], 0, sizeof(Picture)*(h->ref_count[0] - len));
      }
@@@ -287,10 -282,7 +283,10 @@@ int ff_h264_decode_ref_pic_list_reorder
      for(list=0; list<h->list_count; list++){
          for(index= 0; index < h->ref_count[list]; index++){
              if (!h->ref_list[list][index].f.data[0]) {
 -                av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture\n");
 +                int i;
-                 av_log(h->s.avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref_list[list][0].poc);
++                av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref_list[list][0].poc);
 +                for (i=0; i<FF_ARRAY_ELEMS(h->last_pocs); i++)
 +                    h->last_pocs[i] = INT_MIN;
                  if (h->default_ref_list[list][0].f.data[0])
                      h->ref_list[list][index]= h->default_ref_list[list][0];
                  else
@@@ -503,11 -487,11 +497,9 @@@ int ff_generate_sliding_window_mmcos(H2
      MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp;
      int mmco_index = 0, i;
  
 -    assert(h->long_ref_count + h->short_ref_count <= h->sps.ref_frame_count);
 -
      if (h->short_ref_count &&
 -        h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count &&
 +        h->long_ref_count + h->short_ref_count >= h->sps.ref_frame_count &&
-         !(FIELD_PICTURE && !s->first_field &&
-           s->current_picture_ptr->f.reference)) {
+         !(FIELD_PICTURE && !h->first_field && h->cur_pic_ptr->f.reference)) {
          mmco[0].opcode = MMCO_SHORT2UNUSED;
          mmco[0].short_pic_num = h->short_ref[h->short_ref_count - 1]->frame_num;
          mmco_index = 1;
      } else if (!first_slice && mmco_index >= 0 &&
                 (mmco_index != h->mmco_index ||
                  (i = check_opcodes(h->mmco, mmco_temp, mmco_index)))) {
-         av_log(h->s.avctx, AV_LOG_ERROR,
+         av_log(h->avctx, AV_LOG_ERROR,
 -               "Inconsistent MMCO state between slices [%d, %d, %d]\n",
 -               mmco_index, h->mmco_index, i);
 +               "Inconsistent MMCO state between slices [%d, %d]\n",
 +               mmco_index, h->mmco_index);
          return AVERROR_INVALIDDATA;
      }
      return 0;
@@@ -620,11 -603,9 +611,11 @@@ int ff_h264_execute_ref_pic_marking(H26
                  remove_long(h, j, 0);
              }
              h->frame_num=
-             s->current_picture_ptr->frame_num= 0;
+             h->cur_pic_ptr->frame_num= 0;
              h->mmco_reset = 1;
-             s->current_picture_ptr->mmco_reset=1;
+             h->cur_pic_ptr->mmco_reset=1;
 +            for (j = 0; j < MAX_DELAYED_PIC_COUNT; j++)
 +                h->last_pocs[j] = INT_MIN;
              break;
          default: assert(0);
          }
  
      print_short_term(h);
      print_long_term(h);
-     if(err >= 0 && h->long_ref_count==0 && h->short_ref_count<=2 && h->pps.ref_count[0]<=1 + (s->picture_structure != PICT_FRAME) && s->current_picture_ptr->f.pict_type == AV_PICTURE_TYPE_I){
-         s->current_picture_ptr->sync |= 1;
-         if(!h->s.avctx->has_b_frames)
 +
-     return (h->s.avctx->err_recognition & AV_EF_EXPLODE) ? err : 0;
++    if(err >= 0 && h->long_ref_count==0 && h->short_ref_count<=2 && h->pps.ref_count[0]<=1 + (h->picture_structure != PICT_FRAME) && h->cur_pic_ptr->f.pict_type == AV_PICTURE_TYPE_I){
++        h->cur_pic_ptr->sync |= 1;
++        if(!h->avctx->has_b_frames)
 +            h->sync = 2;
 +    }
 +
+     return (h->avctx->err_recognition & AV_EF_EXPLODE) ? err : 0;
  }
  
  int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
      } else if (!first_slice && mmco_index >= 0 &&
                 (mmco_index != h->mmco_index ||
                  (i = check_opcodes(h->mmco, mmco_temp, mmco_index)))) {
-         av_log(h->s.avctx, AV_LOG_ERROR,
+         av_log(h->avctx, AV_LOG_ERROR,
 -               "Inconsistent MMCO state between slices [%d, %d, %d]\n",
 -               mmco_index, h->mmco_index, i);
 +               "Inconsistent MMCO state between slices [%d, %d]\n",
 +               mmco_index, h->mmco_index);
          return AVERROR_INVALIDDATA;
      }
  
@@@ -45,10 -45,9 +45,9 @@@ void ff_h264_reset_sei(H264Context *h) 
  }
  
  static int decode_picture_timing(H264Context *h){
-     MpegEncContext * const s = &h->s;
      if(h->sps.nal_hrd_parameters_present_flag || h->sps.vcl_hrd_parameters_present_flag){
-         h->sei_cpb_removal_delay = get_bits_long(&s->gb, h->sps.cpb_removal_delay_length);
-         h->sei_dpb_output_delay = get_bits_long(&s->gb, h->sps.dpb_output_delay_length);
 -        h->sei_cpb_removal_delay = get_bits(&h->gb, h->sps.cpb_removal_delay_length);
 -        h->sei_dpb_output_delay = get_bits(&h->gb, h->sps.dpb_output_delay_length);
++        h->sei_cpb_removal_delay = get_bits_long(&h->gb, h->sps.cpb_removal_delay_length);
++        h->sei_dpb_output_delay = get_bits_long(&h->gb, h->sps.dpb_output_delay_length);
      }
      if(h->sps.pic_struct_present_flag){
          unsigned int i, num_clock_ts;
      return 0;
  }
  
-     MpegEncContext * const s = &h->s;
 +static int decode_user_data_itu_t_t35(H264Context *h, int size) {
-     skip_bits(&s->gb, 8);   // country_code
-     skip_bits(&s->gb, 16);  // provider_code
-     user_identifier = get_bits_long(&s->gb, 32);
 +    uint32_t user_identifier;
 +    int dtg_active_format;
 +
 +    if (size < 7)
 +        return -1;
 +    size -= 7;
 +
-             skip_bits(&s->gb, 1);
-             if (get_bits(&s->gb, 1)) {
-                 skip_bits(&s->gb, 6);
++    skip_bits(&h->gb, 8);   // country_code
++    skip_bits(&h->gb, 16);  // provider_code
++    user_identifier = get_bits_long(&h->gb, 32);
 +
 +    switch (user_identifier) {
 +        case 0x44544731:    // "DTG1" - AFD_data
 +            if (size < 1)
 +                return -1;
-                 skip_bits(&s->gb, 4);
-                 dtg_active_format = get_bits(&s->gb, 4);
-                 s->avctx->dtg_active_format = dtg_active_format;
++            skip_bits(&h->gb, 1);
++            if (get_bits(&h->gb, 1)) {
++                skip_bits(&h->gb, 6);
 +                if (size < 2)
 +                    return -1;
-                 skip_bits(&s->gb, 6);
++                skip_bits(&h->gb, 4);
++                dtg_active_format = get_bits(&h->gb, 4);
++                h->avctx->dtg_active_format = dtg_active_format;
 +            } else {
-             skip_bits(&s->gb, size * 8);
++                skip_bits(&h->gb, 6);
 +            }
 +            break;
 +        default:
++            skip_bits(&h->gb, size * 8);
 +            break;
 +    }
 +
 +    return 0;
 +}
 +
  static int decode_unregistered_user_data(H264Context *h, int size){
-     MpegEncContext * const s = &h->s;
      uint8_t user_data[16+256];
      int e, build, i;
  
      e= sscanf(user_data+16, "x264 - core %d"/*%s - H.264/MPEG-4 AVC codec - Copyleft 2005 - http://www.videolan.org/x264.html*/, &build);
      if(e==1 && build>0)
          h->x264_build= build;
 +    if(e==1 && build==1 && !strncmp(user_data+16, "x264 - core 0000", 16))
 +        h->x264_build = 67;
  
-     if(s->avctx->debug & FF_DEBUG_BUGS)
-         av_log(s->avctx, AV_LOG_DEBUG, "user data:\"%s\"\n", user_data+16);
+     if(h->avctx->debug & FF_DEBUG_BUGS)
+         av_log(h->avctx, AV_LOG_DEBUG, "user data:\"%s\"\n", user_data+16);
  
      for(; i<size; i++)
-         skip_bits(&s->gb, 8);
+         skip_bits(&h->gb, 8);
  
      return 0;
  }
@@@ -185,14 -141,14 +179,14 @@@ static int decode_buffering_period(H264
      // NOTE: This is really so duplicated in the standard... See H.264, D.1.1
      if (sps->nal_hrd_parameters_present_flag) {
          for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) {
-             h->initial_cpb_removal_delay[sched_sel_idx] = get_bits_long(&s->gb, sps->initial_cpb_removal_delay_length);
-             skip_bits(&s->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset
 -            h->initial_cpb_removal_delay[sched_sel_idx] = get_bits(&h->gb, sps->initial_cpb_removal_delay_length);
++            h->initial_cpb_removal_delay[sched_sel_idx] = get_bits_long(&h->gb, sps->initial_cpb_removal_delay_length);
+             skip_bits(&h->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset
          }
      }
      if (sps->vcl_hrd_parameters_present_flag) {
          for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) {
-             h->initial_cpb_removal_delay[sched_sel_idx] = get_bits_long(&s->gb, sps->initial_cpb_removal_delay_length);
-             skip_bits(&s->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset
 -            h->initial_cpb_removal_delay[sched_sel_idx] = get_bits(&h->gb, sps->initial_cpb_removal_delay_length);
++            h->initial_cpb_removal_delay[sched_sel_idx] = get_bits_long(&h->gb, sps->initial_cpb_removal_delay_length);
+             skip_bits(&h->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset
          }
      }
  
@@@ -208,21 -162,14 +200,21 @@@ int ff_h264_decode_sei(H264Context *h)
  
          type=0;
          do{
-             if (get_bits_left(&s->gb) < 8)
++            if (get_bits_left(&h->gb) < 8)
 +                return -1;
-             type+= show_bits(&s->gb, 8);
-         }while(get_bits(&s->gb, 8) == 255);
+             type+= show_bits(&h->gb, 8);
+         }while(get_bits(&h->gb, 8) == 255);
  
          size=0;
          do{
-             if (get_bits_left(&s->gb) < 8)
++            if (get_bits_left(&h->gb) < 8)
 +                return -1;
-             size+= show_bits(&s->gb, 8);
-         }while(get_bits(&s->gb, 8) == 255);
+             size+= show_bits(&h->gb, 8);
+         }while(get_bits(&h->gb, 8) == 255);
  
-         if(s->avctx->debug&FF_DEBUG_STARTCODE)
-             av_log(h->s.avctx, AV_LOG_DEBUG, "SEI %d len:%d\n", type, size);
++        if(h->avctx->debug&FF_DEBUG_STARTCODE)
++            av_log(h->avctx, AV_LOG_DEBUG, "SEI %d len:%d\n", type, size);
 +
          switch(type){
          case SEI_TYPE_PIC_TIMING: // Picture timing SEI
              if(decode_picture_timing(h) < 0)
@@@ -408,10 -397,8 +408,8 @@@ static void pred8x8_tm_vp8_c(uint8_t *s
   * Set the intra prediction function pointers.
   */
  void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth,
 -                       const int chroma_format_idc)
 +                       int chroma_format_idc)
  {
- //    MpegEncContext * const s = &h->s;
  #undef FUNC
  #undef FUNCC
  #define FUNC(a, depth) a ## _ ## depth
@@@ -143,9 -141,8 +143,9 @@@ typedef struct Picture
      uint16_t *mc_mb_var;        ///< Table for motion compensated MB variances
      uint8_t *mb_mean;           ///< Table for MB luminance
      int b_frame_score;          /* */
-     struct MpegEncContext *owner2; ///< pointer to the MpegEncContext that allocated this picture
+     void *owner2;               ///< pointer to the context that allocated this picture
      int needs_realloc;          ///< Picture needs to be reallocated (eg due to a frame size change)
 +    int period_since_free;      ///< "cycles" since this Picture has been freed
  } Picture;
  
  /**
@@@ -71,8 -74,11 +74,13 @@@ typedef struct 
      int unknown_flag;
      int next_slice_index;
      uint32_t watermark_key;
 +    uint8_t *buf;
 +    int buf_size;
+     int adaptive_quant;
+     int next_p_frame_damaged;
+     int h_edge_pos;
+     int v_edge_pos;
+     int last_frame_output;
  } SVQ3Context;
  
  #define FULLPEL_MODE  1
@@@ -551,26 -555,24 +559,26 @@@ static int svq3_decode_mb(SVQ3Context *
          }
  
          /* decode motion vector(s) and form prediction(s) */
-         if (s->pict_type == AV_PICTURE_TYPE_P) {
-             if (svq3_mc_dir(h, mb_type - 1, mode, 0, 0) < 0)
+         if (h->pict_type == AV_PICTURE_TYPE_P) {
+             if (svq3_mc_dir(s, mb_type - 1, mode, 0, 0) < 0)
                  return -1;
          } else {        /* AV_PICTURE_TYPE_B */
 -            if (mb_type != 2)
 +            if (mb_type != 2) {
-                 if (svq3_mc_dir(h, 0, mode, 0, 0) < 0)
+                 if (svq3_mc_dir(s, 0, mode, 0, 0) < 0)
                      return -1;
 -            else
 +            } else {
                  for (i = 0; i < 4; i++)
-                     memset(s->current_picture.f.motion_val[0][b_xy + i * h->b_stride],
+                     memset(h->cur_pic.f.motion_val[0][b_xy + i * h->b_stride],
                             0, 4 * 2 * sizeof(int16_t));
 -            if (mb_type != 1)
 +            }
 +            if (mb_type != 1) {
-                 if (svq3_mc_dir(h, 0, mode, 1, mb_type == 3) < 0)
+                 if (svq3_mc_dir(s, 0, mode, 1, mb_type == 3) < 0)
                      return -1;
 -            else
 +            } else {
                  for (i = 0; i < 4; i++)
-                     memset(s->current_picture.f.motion_val[1][b_xy + i * h->b_stride],
+                     memset(h->cur_pic.f.motion_val[1][b_xy + i * h->b_stride],
                             0, 4 * 2 * sizeof(int16_t));
 +            }
          }
  
          mb_type = MB_TYPE_16x16;
  
              /* decode prediction codes for luma blocks */
              for (i = 0; i < 16; i += 2) {
-                 vlc = svq3_get_ue_golomb(&s->gb);
+                 vlc = svq3_get_ue_golomb(&h->gb);
  
 -                if (vlc >= 25) {
 +                if (vlc >= 25U) {
-                     av_log(h->s.avctx, AV_LOG_ERROR, "luma prediction:%d\n", vlc);
+                     av_log(h->avctx, AV_LOG_ERROR, "luma prediction:%d\n", vlc);
                      return -1;
                  }
  
      }
  
      if (!IS_INTRA16x16(mb_type) &&
-         (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B)) {
-         if ((vlc = svq3_get_ue_golomb(&s->gb)) >= 48U){
-             av_log(h->s.avctx, AV_LOG_ERROR, "cbp_vlc=%d\n", vlc);
+         (!IS_SKIP(mb_type) || h->pict_type == AV_PICTURE_TYPE_B)) {
 -        if ((vlc = svq3_get_ue_golomb(&h->gb)) >= 48) {
++        if ((vlc = svq3_get_ue_golomb(&h->gb)) >= 48U){
+             av_log(h->avctx, AV_LOG_ERROR, "cbp_vlc=%d\n", vlc);
              return -1;
          }
  
@@@ -856,11 -866,9 +872,10 @@@ static av_cold int svq3_decode_init(AVC
      if (ff_h264_decode_init(avctx) < 0)
          return -1;
  
-     s->flags           = avctx->flags;
-     s->flags2          = avctx->flags2;
-     s->unrestricted_mv = 1;
+     h->flags           = avctx->flags;
      h->is_complex      = 1;
 +    h->sps.chroma_format_idc = 1;
+     h->picture_structure = PICT_FRAME;
      avctx->pix_fmt     = avctx->codec->pix_fmts[0];
  
      h->chroma_qp[0] = h->chroma_qp[1] = 4;
@@@ -1010,12 -1058,11 +1065,12 @@@ static int get_buffer(AVCodecContext *a
  static int svq3_decode_frame(AVCodecContext *avctx, void *data,
                               int *got_frame, AVPacket *avpkt)
  {
-     SVQ3Context *svq3  = avctx->priv_data;
-     H264Context *h     = &svq3->h;
-     MpegEncContext *s  = &h->s;
 -    const uint8_t *buf = avpkt->data;
+     SVQ3Context *s     = avctx->priv_data;
+     H264Context *h     = &s->h;
      int buf_size       = avpkt->size;
-     int m, left;
++    int left;
 +    uint8_t *buf;
+     int ret, m, i;
  
      /* special case for last picture */
      if (buf_size == 0) {
          return 0;
      }
  
-     s->mb_x = s->mb_y = h->mb_xy = 0;
 -    init_get_bits(&h->gb, buf, 8 * buf_size);
 -
+     h->mb_x = h->mb_y = h->mb_xy = 0;
  
-     if (svq3->watermark_key) {
-         av_fast_malloc(&svq3->buf, &svq3->buf_size,
++    if (s->watermark_key) {
++        av_fast_malloc(&s->buf, &s->buf_size,
 +                       buf_size+FF_INPUT_BUFFER_PADDING_SIZE);
-         if (!svq3->buf)
++        if (!s->buf)
 +            return AVERROR(ENOMEM);
-         memcpy(svq3->buf, avpkt->data, buf_size);
-         buf = svq3->buf;
++        memcpy(s->buf, avpkt->data, buf_size);
++        buf = s->buf;
 +    } else {
 +        buf = avpkt->data;
 +    }
 +
-     init_get_bits(&s->gb, buf, 8 * buf_size);
++    init_get_bits(&h->gb, buf, 8 * buf_size);
 +
      if (svq3_decode_slice_header(avctx))
          return -1;
  
              if (mb_type != 0)
                  ff_h264_hl_decode_mb(h);
  
-             if (s->pict_type != AV_PICTURE_TYPE_B && !s->low_delay)
-                 s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] =
-                     (s->pict_type == AV_PICTURE_TYPE_P && mb_type < 8) ? (mb_type - 1) : -1;
+             if (h->pict_type != AV_PICTURE_TYPE_B && !h->low_delay)
+                 h->cur_pic.f.mb_type[h->mb_x + h->mb_y * h->mb_stride] =
+                     (h->pict_type == AV_PICTURE_TYPE_P && mb_type < 8) ? (mb_type - 1) : -1;
          }
  
-         ff_mpeg_draw_horiz_band(s, 16 * s->mb_y, 16);
+         ff_draw_horiz_band(avctx, &h->dsp, s->cur_pic, s->last_pic->f.data[0] ? s->last_pic : NULL,
+                            16 * h->mb_y, 16, h->picture_structure, 0, 1,
+                            h->low_delay, h->mb_height * 16, h->mb_width * 16);
      }
  
-     left = buf_size*8 - get_bits_count(&s->gb);
++    left = buf_size*8 - get_bits_count(&h->gb);
 +
-     if (s->mb_y != s->mb_height || s->mb_x != s->mb_width) {
-         av_log(avctx, AV_LOG_INFO, "frame num %d incomplete pic x %d y %d left %d\n", avctx->frame_number, s->mb_y, s->mb_x, left);
++    if (h->mb_y != h->mb_height || h->mb_x != h->mb_width) {
++        av_log(avctx, AV_LOG_INFO, "frame num %d incomplete pic x %d y %d left %d\n", avctx->frame_number, h->mb_y, h->mb_x, left);
 +        //av_hex_dump(stderr, buf+buf_size-8, 8);
 +    }
 +
 +    if (left < 0) {
 +        av_log(avctx, AV_LOG_ERROR, "frame num %d left %d\n", avctx->frame_number, left);
 +        return -1;
 +    }
 +
-     ff_MPV_frame_end(s);
-     if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay)
-         *(AVFrame *)data = s->current_picture.f;
+     if (h->pict_type == AV_PICTURE_TYPE_B || h->low_delay)
+         *(AVFrame *)data = s->cur_pic->f;
      else
-         *(AVFrame *)data = s->last_picture.f;
+         *(AVFrame *)data = s->last_pic->f;
  
      /* Do not output the last pic after seeking. */
-     if (s->last_picture_ptr || s->low_delay)
+     if (s->last_pic->f.data[0] || h->low_delay)
          *got_frame = 1;
  
+     if (h->pict_type != AV_PICTURE_TYPE_B) {
+         FFSWAP(Picture*, s->cur_pic, s->next_pic);
+     }
      return buf_size;
  }
  
+ static void free_picture(AVCodecContext *avctx, Picture *pic)
+ {
+     int i;
+     for (i = 0; i < 2; i++) {
+         av_freep(&pic->motion_val_base[i]);
+         av_freep(&pic->f.ref_index[i]);
+     }
+     av_freep(&pic->mb_type_base);
+     if (pic->f.data[0])
+         avctx->release_buffer(avctx, &pic->f);
+     av_freep(&pic);
+ }
  static int svq3_decode_end(AVCodecContext *avctx)
  {
-     SVQ3Context *svq3 = avctx->priv_data;
-     H264Context *h    = &svq3->h;
-     MpegEncContext *s = &h->s;
+     SVQ3Context *s = avctx->priv_data;
+     H264Context *h = &s->h;
  
-     ff_h264_free_context(h);
+     free_picture(avctx, s->cur_pic);
+     free_picture(avctx, s->next_pic);
+     free_picture(avctx, s->last_pic);
  
-     ff_MPV_common_end(s);
+     ff_h264_free_context(h);
  
-     av_freep(&svq3->buf);
-     svq3->buf_size = 0;
++    av_freep(&s->buf);
++    s->buf_size = 0;
 +
      return 0;
  }
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge