libavcodec/mpegvideo.c
de6d9b64
 /*
  * The simplest mpeg encoder (well, it was the simplest!)
406792e7
  * Copyright (c) 2000,2001 Fabrice Bellard
8f2ab833
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
de6d9b64
  *
7b94177e
  * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
  *
b78e7197
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
ff4ec49e
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
b78e7197
  * version 2.1 of the License, or (at your option) any later version.
de6d9b64
  *
b78e7197
  * FFmpeg is distributed in the hope that it will be useful,
de6d9b64
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
ff4ec49e
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
de6d9b64
  *
ff4ec49e
  * You should have received a copy of the GNU Lesser General Public
b78e7197
  * License along with FFmpeg; if not, write to the Free Software
5509bffa
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
de6d9b64
  */
115329f1
 
983e3246
 /**
bad5537e
  * @file libavcodec/mpegvideo.c
983e3246
  * The simplest mpeg encoder (well, it was the simplest!).
115329f1
  */
 
de6d9b64
 #include "avcodec.h"
 #include "dsputil.h"
 #include "mpegvideo.h"
3ada94ba
 #include "mpegvideo_common.h"
d9c9259f
 #include "mjpegenc.h"
15025553
 #include "msmpeg4.h"
65e4c8c9
 #include "faandct.h"
4440bd0d
 #include "xvmc_internal.h"
e96682e6
 #include <limits.h>
de6d9b64
 
e4eadb4b
 //#undef NDEBUG
 //#include <assert.h>
2ad1516a
 
115329f1
 static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
21af69f7
                                    DCTELEM *block, int n, int qscale);
115329f1
 static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s,
9dbf1ddd
                                    DCTELEM *block, int n, int qscale);
d50635cd
 static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s,
                                    DCTELEM *block, int n, int qscale);
e27b6e62
 static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s,
                                    DCTELEM *block, int n, int qscale);
d50635cd
 static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s,
                                    DCTELEM *block, int n, int qscale);
115329f1
 static void dct_unquantize_h263_intra_c(MpegEncContext *s,
d50635cd
                                   DCTELEM *block, int n, int qscale);
115329f1
 static void dct_unquantize_h263_inter_c(MpegEncContext *s,
21af69f7
                                   DCTELEM *block, int n, int qscale);
3d9fccbf
 
de6d9b64
 
 /* enable all paranoid tests for rounding, overflows, etc... */
 //#define PARANOID
 
 //#define DEBUG
 
101bea5f
 
332f9ac4
 static const uint8_t ff_default_chroma_qscale_table[32]={
 //  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
     0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
 };
 
6cbe71bd
 const uint8_t ff_mpeg1_dc_scale_table[128]={
 //  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 };
 
09a9b45e
 const enum PixelFormat ff_pixfmt_list_420[] = {
044f0296
     PIX_FMT_YUV420P,
     PIX_FMT_NONE
 };
 
 const enum PixelFormat ff_hwaccel_pixfmt_list_420[] = {
09a9b45e
     PIX_FMT_YUV420P,
     PIX_FMT_NONE
 };
2ad1516a
 
82fcbc14
 const uint8_t *ff_find_start_code(const uint8_t * restrict p, const uint8_t *end, uint32_t * restrict state){
     int i;
 
8cb90572
     assert(p<=end);
     if(p>=end)
         return end;
 
82fcbc14
     for(i=0; i<3; i++){
         uint32_t tmp= *state << 8;
         *state= tmp + *(p++);
         if(tmp == 0x100 || p==end)
             return p;
     }
 
     while(p<end){
809b2a30
         if     (p[-1] > 1      ) p+= 3;
         else if(p[-2]          ) p+= 2;
         else if(p[-3]|(p[-1]-1)) p++;
82fcbc14
         else{
             p++;
             break;
         }
     }
 
809b2a30
     p= FFMIN(p, end)-4;
f49f6e88
     *state= AV_RB32(p);
82fcbc14
 
     return p+4;
 }
 
defdfc9a
 /* init common dct for both encoder and decoder */
5ef251e5
 av_cold int ff_dct_common_init(MpegEncContext *s)
de6d9b64
 {
d50635cd
     s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c;
     s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_c;
     s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_c;
     s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_c;
     s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_c;
e27b6e62
     if(s->flags & CODEC_FLAG_BITEXACT)
         s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact;
d50635cd
     s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c;
b0368839
 
b250f9c6
 #if   HAVE_MMX
e4eadb4b
     MPV_common_init_mmx(s);
b250f9c6
 #elif ARCH_ALPHA
e0580f8c
     MPV_common_init_axp(s);
b250f9c6
 #elif CONFIG_MLIB
c7e07931
     MPV_common_init_mlib(s);
b250f9c6
 #elif HAVE_MMI
5917d17c
     MPV_common_init_mmi(s);
b250f9c6
 #elif ARCH_ARM
a2fc0f6a
     MPV_common_init_arm(s);
b250f9c6
 #elif HAVE_ALTIVEC
f62a9a46
     MPV_common_init_altivec(s);
b250f9c6
 #elif ARCH_BFIN
1a822d30
     MPV_common_init_bfin(s);
 #endif
676e200c
 
2ad1516a
     /* load & permutate scantables
115329f1
        note: only wmv uses different ones
2ad1516a
     */
bb198e19
     if(s->alternate_scan){
         ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable  , ff_alternate_vertical_scan);
         ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable  , ff_alternate_vertical_scan);
     }else{
         ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable  , ff_zigzag_direct);
         ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable  , ff_zigzag_direct);
     }
3d2e8cce
     ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
     ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
d930ef19
 
defdfc9a
     return 0;
 }
 
8d2fc163
 void ff_copy_picture(Picture *dst, Picture *src){
6571e41d
     *dst = *src;
     dst->type= FF_BUFFER_TYPE_COPY;
 }
 
1e491e29
 /**
4e00e76b
  * allocates a Picture
  * The pixels are allocated/set by calling get_buffer() if shared=0
1e491e29
  */
3ada94ba
 int alloc_picture(MpegEncContext *s, Picture *pic, int shared){
755bfeab
     const int big_mb_num= s->mb_stride*(s->mb_height+1) + 1; //the +1 is needed so memset(,,stride*height) does not sig11
7bc9090a
     const int mb_array_size= s->mb_stride*s->mb_height;
b40cd4e0
     const int b8_array_size= s->b8_stride*s->mb_height*2;
     const int b4_array_size= s->b4_stride*s->mb_height*4;
0da71265
     int i;
29d2dc59
     int r= -1;
115329f1
 
4e00e76b
     if(shared){
         assert(pic->data[0]);
         assert(pic->type == 0 || pic->type == FF_BUFFER_TYPE_SHARED);
         pic->type= FF_BUFFER_TYPE_SHARED;
     }else{
         assert(!pic->data[0]);
115329f1
 
492cd3a9
         r= s->avctx->get_buffer(s->avctx, (AVFrame*)pic);
115329f1
 
4e00e76b
         if(r<0 || !pic->age || !pic->type || !pic->data[0]){
bb270c08
             av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %d %p)\n", r, pic->age, pic->type, pic->data[0]);
4e00e76b
             return -1;
         }
 
         if(s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1])){
9b879566
             av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (stride changed)\n");
29d2dc59
             s->avctx->release_buffer(s->avctx, (AVFrame*)pic);
4e00e76b
             return -1;
         }
 
         if(pic->linesize[1] != pic->linesize[2]){
bb628dae
             av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (uv stride mismatch)\n");
29d2dc59
             s->avctx->release_buffer(s->avctx, (AVFrame*)pic);
4e00e76b
             return -1;
         }
 
         s->linesize  = pic->linesize[0];
         s->uvlinesize= pic->linesize[1];
1e491e29
     }
115329f1
 
4e00e76b
     if(pic->qscale_table==NULL){
115329f1
         if (s->encoding) {
7bc9090a
             CHECKED_ALLOCZ(pic->mb_var   , mb_array_size * sizeof(int16_t))
             CHECKED_ALLOCZ(pic->mc_mb_var, mb_array_size * sizeof(int16_t))
             CHECKED_ALLOCZ(pic->mb_mean  , mb_array_size * sizeof(int8_t))
4e00e76b
         }
1e491e29
 
7bc9090a
         CHECKED_ALLOCZ(pic->mbskip_table , mb_array_size * sizeof(uint8_t)+2) //the +2 is for the slice end check
e4eadb4b
         CHECKED_ALLOCZ(pic->qscale_table , mb_array_size * sizeof(uint8_t))
0063c05c
         CHECKED_ALLOCZ(pic->mb_type_base , (big_mb_num + s->mb_stride) * sizeof(uint32_t))
         pic->mb_type= pic->mb_type_base + 2*s->mb_stride+1;
0da71265
         if(s->out_format == FMT_H264){
             for(i=0; i<2; i++){
02dc8983
                 CHECKED_ALLOCZ(pic->motion_val_base[i], 2 * (b4_array_size+4)  * sizeof(int16_t))
                 pic->motion_val[i]= pic->motion_val_base[i]+4;
7c4f71c4
                 CHECKED_ALLOCZ(pic->ref_index[i], b8_array_size * sizeof(uint8_t))
b40cd4e0
             }
5ea4b18d
             pic->motion_subsample_log2= 2;
0c9bbaec
         }else if(s->out_format == FMT_H263 || s->encoding || (s->avctx->debug&FF_DEBUG_MV) || (s->avctx->debug_mv)){
b40cd4e0
             for(i=0; i<2; i++){
02dc8983
                 CHECKED_ALLOCZ(pic->motion_val_base[i], 2 * (b8_array_size+4) * sizeof(int16_t))
                 pic->motion_val[i]= pic->motion_val_base[i]+4;
7c4f71c4
                 CHECKED_ALLOCZ(pic->ref_index[i], b8_array_size * sizeof(uint8_t))
0da71265
             }
5ea4b18d
             pic->motion_subsample_log2= 3;
0da71265
         }
8289c6fa
         if(s->avctx->debug&FF_DEBUG_DCT_COEFF) {
             CHECKED_ALLOCZ(pic->dct_coeff, 64 * mb_array_size * sizeof(DCTELEM)*6)
         }
7bc9090a
         pic->qstride= s->mb_stride;
fa384dcc
         CHECKED_ALLOCZ(pic->pan_scan , 1 * sizeof(AVPanScan))
4e00e76b
     }
0da71265
 
90b5b51e
     /* It might be nicer if the application would keep track of these
      * but it would require an API change. */
f943e138
     memmove(s->prev_pict_types+1, s->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE-1);
5b0e7dac
     s->prev_pict_types[0]= s->dropable ? FF_B_TYPE : s->pict_type;
9701840b
     if(pic->age < PREV_PICT_TYPES_BUFFER_SIZE && s->prev_pict_types[pic->age] == FF_B_TYPE)
90b5b51e
         pic->age= INT_MAX; // Skipped MBs in B-frames are quite rare in MPEG-1/2 and it is a bit tricky to skip them anyway.
115329f1
 
1e491e29
     return 0;
 fail: //for the CHECKED_ALLOCZ macro
29d2dc59
     if(r>=0)
         s->avctx->release_buffer(s->avctx, (AVFrame*)pic);
1e491e29
     return -1;
 }
 
4e00e76b
 /**
  * deallocates a picture
  */
1e491e29
 static void free_picture(MpegEncContext *s, Picture *pic){
     int i;
4e00e76b
 
     if(pic->data[0] && pic->type!=FF_BUFFER_TYPE_SHARED){
492cd3a9
         s->avctx->release_buffer(s->avctx, (AVFrame*)pic);
4e00e76b
     }
 
1e491e29
     av_freep(&pic->mb_var);
     av_freep(&pic->mc_mb_var);
     av_freep(&pic->mb_mean);
     av_freep(&pic->mbskip_table);
     av_freep(&pic->qscale_table);
0da71265
     av_freep(&pic->mb_type_base);
8289c6fa
     av_freep(&pic->dct_coeff);
fa384dcc
     av_freep(&pic->pan_scan);
0da71265
     pic->mb_type= NULL;
     for(i=0; i<2; i++){
b40cd4e0
         av_freep(&pic->motion_val_base[i]);
0da71265
         av_freep(&pic->ref_index[i]);
     }
115329f1
 
d90cf87b
     if(pic->type == FF_BUFFER_TYPE_SHARED){
4e00e76b
         for(i=0; i<4; i++){
             pic->base[i]=
             pic->data[i]= NULL;
         }
115329f1
         pic->type= 0;
1e491e29
     }
 }
 
9c3d33d6
 static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base){
     int i;
 
115329f1
     // edge emu needs blocksize + filter length - 1 (=17x17 for halfpel / 21x21 for h264)
5d18eaad
     CHECKED_ALLOCZ(s->allocated_edge_emu_buffer, (s->width+64)*2*21*2); //(width + edge + align)*interlaced*MBsize*tolerance
     s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*21;
9c3d33d6
 
755bfeab
      //FIXME should be linesize instead of s->width*2 but that is not known before get_buffer()
115329f1
     CHECKED_ALLOCZ(s->me.scratchpad,  (s->width+64)*4*16*2*sizeof(uint8_t))
a6f2c0d6
     s->me.temp=         s->me.scratchpad;
9c3d33d6
     s->rd_scratchpad=   s->me.scratchpad;
     s->b_scratchpad=    s->me.scratchpad;
     s->obmc_scratchpad= s->me.scratchpad + 16;
     if (s->encoding) {
         CHECKED_ALLOCZ(s->me.map      , ME_MAP_SIZE*sizeof(uint32_t))
         CHECKED_ALLOCZ(s->me.score_map, ME_MAP_SIZE*sizeof(uint32_t))
         if(s->avctx->noise_reduction){
             CHECKED_ALLOCZ(s->dct_error_sum, 2 * 64 * sizeof(int))
         }
115329f1
     }
5e5c247a
     CHECKED_ALLOCZ(s->blocks, 64*12*2 * sizeof(DCTELEM))
9c3d33d6
     s->block= s->blocks[0];
 
     for(i=0;i<12;i++){
21effaa4
         s->pblocks[i] = &s->block[i];
9c3d33d6
     }
     return 0;
 fail:
     return -1; //free() through MPV_common_end()
 }
 
 static void free_duplicate_context(MpegEncContext *s){
     if(s==NULL) return;
 
     av_freep(&s->allocated_edge_emu_buffer); s->edge_emu_buffer= NULL;
     av_freep(&s->me.scratchpad);
a6f2c0d6
     s->me.temp=
115329f1
     s->rd_scratchpad=
     s->b_scratchpad=
9c3d33d6
     s->obmc_scratchpad= NULL;
115329f1
 
9c3d33d6
     av_freep(&s->dct_error_sum);
     av_freep(&s->me.map);
     av_freep(&s->me.score_map);
     av_freep(&s->blocks);
     s->block= NULL;
 }
 
 static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src){
 #define COPY(a) bak->a= src->a
     COPY(allocated_edge_emu_buffer);
     COPY(edge_emu_buffer);
     COPY(me.scratchpad);
a6f2c0d6
     COPY(me.temp);
9c3d33d6
     COPY(rd_scratchpad);
     COPY(b_scratchpad);
     COPY(obmc_scratchpad);
     COPY(me.map);
     COPY(me.score_map);
     COPY(blocks);
     COPY(block);
     COPY(start_mb_y);
     COPY(end_mb_y);
     COPY(me.map_generation);
     COPY(pb);
     COPY(dct_error_sum);
da16b204
     COPY(dct_count[0]);
     COPY(dct_count[1]);
9c3d33d6
 #undef COPY
 }
 
c62c07d3
 void ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src){
9c3d33d6
     MpegEncContext bak;
c62c07d3
     int i;
9c3d33d6
     //FIXME copy only needed parts
 //START_TIMER
     backup_duplicate_context(&bak, dst);
     memcpy(dst, src, sizeof(MpegEncContext));
     backup_duplicate_context(dst, &bak);
c62c07d3
     for(i=0;i<12;i++){
21effaa4
         dst->pblocks[i] = &dst->block[i];
c62c07d3
     }
9c3d33d6
 //STOP_TIMER("update_duplicate_context") //about 10k cycles / 0.01 sec for 1000frames on 1ghz with 2 threads
 }
 
3edcacde
 /**
  * sets the given MpegEncContext to common defaults (same for encoding and decoding).
  * the changed fields will not depend upon the prior state of the MpegEncContext.
  */
3ada94ba
 void MPV_common_defaults(MpegEncContext *s){
3edcacde
     s->y_dc_scale_table=
     s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
     s->chroma_qscale_table= ff_default_chroma_qscale_table;
     s->progressive_frame= 1;
     s->progressive_sequence= 1;
     s->picture_structure= PICT_FRAME;
 
     s->coded_picture_number = 0;
     s->picture_number = 0;
     s->input_picture_number = 0;
 
     s->picture_in_gop_number = 0;
7976241a
 
     s->f_code = 1;
     s->b_code = 1;
3edcacde
 }
 
 /**
  * sets the given MpegEncContext to defaults for decoding.
  * the changed fields will not depend upon the prior state of the MpegEncContext.
  */
 void MPV_decode_defaults(MpegEncContext *s){
     MPV_common_defaults(s);
 }
 
 /**
  * init common structure for both encoder and decoder.
  * this assumes that some variables like width/height are already set
  */
5ef251e5
 av_cold int MPV_common_init(MpegEncContext *s)
defdfc9a
 {
afebe2f7
     int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y, threads;
defdfc9a
 
fdb52bcc
     s->mb_height = (s->height + 15) / 16;
 
9cfc1b3a
     if(s->avctx->pix_fmt == PIX_FMT_NONE){
         av_log(s->avctx, AV_LOG_ERROR, "decoding to PIX_FMT_NONE is not supported.\n");
         return -1;
     }
 
fdb52bcc
     if(s->avctx->thread_count > MAX_THREADS || (s->avctx->thread_count > s->mb_height && s->mb_height)){
000a9c02
         av_log(s->avctx, AV_LOG_ERROR, "too many threads\n");
         return -1;
     }
 
0ecca7a4
     if((s->width || s->height) && avcodec_check_dimensions(s->avctx, s->width, s->height))
         return -1;
 
b0368839
     dsputil_init(&s->dsp, s->avctx);
6180ade7
     ff_dct_common_init(s);
eb4b3dd3
 
9fee1e23
     s->flags= s->avctx->flags;
303e50e6
     s->flags2= s->avctx->flags2;
defdfc9a
 
1e491e29
     s->mb_width  = (s->width  + 15) / 16;
7bc9090a
     s->mb_stride = s->mb_width + 1;
b40cd4e0
     s->b8_stride = s->mb_width*2 + 1;
     s->b4_stride = s->mb_width*4 + 1;
7bc9090a
     mb_array_size= s->mb_height * s->mb_stride;
bb198e19
     mv_table_size= (s->mb_height+2) * s->mb_stride + 1;
eb4b3dd3
 
ffdff4d7
     /* set chroma shifts */
     avcodec_get_chroma_sub_sample(s->avctx->pix_fmt,&(s->chroma_x_shift),
                                                     &(s->chroma_y_shift) );
 
b5a093b3
     /* set default edge pos, will be overriden in decode_header if needed */
     s->h_edge_pos= s->mb_width*16;
     s->v_edge_pos= s->mb_height*16;
eb4b3dd3
 
     s->mb_num = s->mb_width * s->mb_height;
115329f1
 
7bc9090a
     s->block_wrap[0]=
     s->block_wrap[1]=
     s->block_wrap[2]=
137c8468
     s->block_wrap[3]= s->b8_stride;
7bc9090a
     s->block_wrap[4]=
137c8468
     s->block_wrap[5]= s->mb_stride;
115329f1
 
137c8468
     y_size = s->b8_stride * (2 * s->mb_height + 1);
     c_size = s->mb_stride * (s->mb_height + 1);
eb4b3dd3
     yc_size = y_size + 2 * c_size;
115329f1
 
202ef8b8
     /* convert fourcc to upper case */
17662955
     s->codec_tag=          toupper( s->avctx->codec_tag     &0xFF)
7004ffb3
                         + (toupper((s->avctx->codec_tag>>8 )&0xFF)<<8 )
115329f1
                         + (toupper((s->avctx->codec_tag>>16)&0xFF)<<16)
7004ffb3
                         + (toupper((s->avctx->codec_tag>>24)&0xFF)<<24);
b5a093b3
 
17662955
     s->stream_codec_tag=          toupper( s->avctx->stream_codec_tag     &0xFF)
541ae140
                                + (toupper((s->avctx->stream_codec_tag>>8 )&0xFF)<<8 )
115329f1
                                + (toupper((s->avctx->stream_codec_tag>>16)&0xFF)<<16)
541ae140
                                + (toupper((s->avctx->stream_codec_tag>>24)&0xFF)<<24);
 
492cd3a9
     s->avctx->coded_frame= (AVFrame*)&s->current_picture;
1e491e29
 
7bc9090a
     CHECKED_ALLOCZ(s->mb_index2xy, (s->mb_num+1)*sizeof(int)) //error ressilience code looks cleaner with this
     for(y=0; y<s->mb_height; y++){
         for(x=0; x<s->mb_width; x++){
             s->mb_index2xy[ x + y*s->mb_width ] = x + y*s->mb_stride;
         }
     }
     s->mb_index2xy[ s->mb_height*s->mb_width ] = (s->mb_height-1)*s->mb_stride + s->mb_width; //FIXME really needed?
115329f1
 
37fbfd0a
     if (s->encoding) {
9dbcbd92
         /* Allocate MV tables */
7bc9090a
         CHECKED_ALLOCZ(s->p_mv_table_base            , mv_table_size * 2 * sizeof(int16_t))
         CHECKED_ALLOCZ(s->b_forw_mv_table_base       , mv_table_size * 2 * sizeof(int16_t))
         CHECKED_ALLOCZ(s->b_back_mv_table_base       , mv_table_size * 2 * sizeof(int16_t))
         CHECKED_ALLOCZ(s->b_bidir_forw_mv_table_base , mv_table_size * 2 * sizeof(int16_t))
         CHECKED_ALLOCZ(s->b_bidir_back_mv_table_base , mv_table_size * 2 * sizeof(int16_t))
         CHECKED_ALLOCZ(s->b_direct_mv_table_base     , mv_table_size * 2 * sizeof(int16_t))
         s->p_mv_table           = s->p_mv_table_base            + s->mb_stride + 1;
         s->b_forw_mv_table      = s->b_forw_mv_table_base       + s->mb_stride + 1;
         s->b_back_mv_table      = s->b_back_mv_table_base       + s->mb_stride + 1;
         s->b_bidir_forw_mv_table= s->b_bidir_forw_mv_table_base + s->mb_stride + 1;
         s->b_bidir_back_mv_table= s->b_bidir_back_mv_table_base + s->mb_stride + 1;
         s->b_direct_mv_table    = s->b_direct_mv_table_base     + s->mb_stride + 1;
7f2fe444
 
6b460aa3
         if(s->msmpeg4_version){
             CHECKED_ALLOCZ(s->ac_stats, 2*2*(MAX_LEVEL+1)*(MAX_RUN+1)*2*sizeof(int));
         }
3aa102be
         CHECKED_ALLOCZ(s->avctx->stats_out, 256);
7bc9090a
 
         /* Allocate MB type table */
bb198e19
         CHECKED_ALLOCZ(s->mb_type  , mb_array_size * sizeof(uint16_t)) //needed for encoding
115329f1
 
158c7f05
         CHECKED_ALLOCZ(s->lambda_table, mb_array_size * sizeof(int))
115329f1
 
7e4995c3
         CHECKED_ALLOCZ(s->q_intra_matrix, 64*32 * sizeof(int))
         CHECKED_ALLOCZ(s->q_inter_matrix, 64*32 * sizeof(int))
642ccefb
         CHECKED_ALLOCZ(s->q_intra_matrix16, 64*32*2 * sizeof(uint16_t))
         CHECKED_ALLOCZ(s->q_inter_matrix16, 64*32*2 * sizeof(uint16_t))
9d9e3172
         CHECKED_ALLOCZ(s->input_picture, MAX_PICTURE_COUNT * sizeof(Picture*))
         CHECKED_ALLOCZ(s->reordered_input_picture, MAX_PICTURE_COUNT * sizeof(Picture*))
115329f1
 
821cb11f
         if(s->avctx->noise_reduction){
             CHECKED_ALLOCZ(s->dct_offset, 2 * 64 * sizeof(uint16_t))
         }
37fbfd0a
     }
b465449e
     CHECKED_ALLOCZ(s->picture, MAX_PICTURE_COUNT * sizeof(Picture))
 
7bc9090a
     CHECKED_ALLOCZ(s->error_status_table, mb_array_size*sizeof(uint8_t))
115329f1
 
bb198e19
     if(s->codec_id==CODEC_ID_MPEG4 || (s->flags & CODEC_FLAG_INTERLACED_ME)){
4d2858de
         /* interlaced direct mode decoding tables */
bb198e19
             for(i=0; i<2; i++){
                 int j, k;
                 for(j=0; j<2; j++){
                     for(k=0; k<2; k++){
                         CHECKED_ALLOCZ(s->b_field_mv_table_base[i][j][k]     , mv_table_size * 2 * sizeof(int16_t))
                         s->b_field_mv_table[i][j][k]    = s->b_field_mv_table_base[i][j][k]     + s->mb_stride + 1;
                     }
                     CHECKED_ALLOCZ(s->b_field_select_table[i][j]     , mb_array_size * 2 * sizeof(uint8_t))
                     CHECKED_ALLOCZ(s->p_field_mv_table_base[i][j]     , mv_table_size * 2 * sizeof(int16_t))
                     s->p_field_mv_table[i][j]    = s->p_field_mv_table_base[i][j]     + s->mb_stride + 1;
                 }
                 CHECKED_ALLOCZ(s->p_field_select_table[i]      , mb_array_size * 2 * sizeof(uint8_t))
             }
de6d9b64
     }
6e2d5f1a
     if (s->out_format == FMT_H263) {
de6d9b64
         /* ac values */
137c8468
         CHECKED_ALLOCZ(s->ac_val_base, yc_size * sizeof(int16_t) * 16);
         s->ac_val[0] = s->ac_val_base + s->b8_stride + 1;
         s->ac_val[1] = s->ac_val_base + y_size + s->mb_stride + 1;
de6d9b64
         s->ac_val[2] = s->ac_val[1] + c_size;
115329f1
 
de6d9b64
         /* cbp values */
137c8468
         CHECKED_ALLOCZ(s->coded_block_base, y_size);
         s->coded_block= s->coded_block_base + s->b8_stride + 1;
115329f1
 
7f2fe444
         /* cbp, ac_pred, pred_dir */
7bc9090a
         CHECKED_ALLOCZ(s->cbp_table  , mb_array_size * sizeof(uint8_t))
         CHECKED_ALLOCZ(s->pred_dir_table, mb_array_size * sizeof(uint8_t))
5b3438c6
     }
115329f1
 
8b32880c
     if (s->h263_pred || s->h263_plus || !s->encoding) {
         /* dc values */
         //MN: we need these for error resilience of intra-frames
137c8468
         CHECKED_ALLOCZ(s->dc_val_base, yc_size * sizeof(int16_t));
         s->dc_val[0] = s->dc_val_base + s->b8_stride + 1;
         s->dc_val[1] = s->dc_val_base + y_size + s->mb_stride + 1;
8b32880c
         s->dc_val[2] = s->dc_val[1] + c_size;
         for(i=0;i<yc_size;i++)
137c8468
             s->dc_val_base[i] = 1024;
8b32880c
     }
 
7806197d
     /* which mb is a intra block */
7bc9090a
     CHECKED_ALLOCZ(s->mbintra_table, mb_array_size);
     memset(s->mbintra_table, 1, mb_array_size);
115329f1
 
3bb4e23a
     /* init macroblock skip table */
7bc9090a
     CHECKED_ALLOCZ(s->mbskip_table, mb_array_size+2);
4d2858de
     //Note the +1 is for a quicker mpeg4 slice_end detection
f943e138
     CHECKED_ALLOCZ(s->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE);
115329f1
 
d7425f59
     s->parse_context.state= -1;
0c9bbaec
     if((s->avctx->debug&(FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) || (s->avctx->debug_mv)){
        s->visualization_buffer[0] = av_malloc((s->mb_width*16 + 2*EDGE_WIDTH) * s->mb_height*16 + 2*EDGE_WIDTH);
014d2f05
        s->visualization_buffer[1] = av_malloc((s->mb_width*16 + 2*EDGE_WIDTH) * s->mb_height*16 + 2*EDGE_WIDTH);
        s->visualization_buffer[2] = av_malloc((s->mb_width*16 + 2*EDGE_WIDTH) * s->mb_height*16 + 2*EDGE_WIDTH);
0c9bbaec
     }
d7425f59
 
de6d9b64
     s->context_initialized = 1;
9c3d33d6
 
     s->thread_context[0]= s;
79db7ac6
     threads = s->avctx->thread_count;
afebe2f7
 
     for(i=1; i<threads; i++){
9c3d33d6
         s->thread_context[i]= av_malloc(sizeof(MpegEncContext));
         memcpy(s->thread_context[i], s, sizeof(MpegEncContext));
     }
 
afebe2f7
     for(i=0; i<threads; i++){
9c3d33d6
         if(init_duplicate_context(s->thread_context[i], s) < 0)
            goto fail;
         s->thread_context[i]->start_mb_y= (s->mb_height*(i  ) + s->avctx->thread_count/2) / s->avctx->thread_count;
         s->thread_context[i]->end_mb_y  = (s->mb_height*(i+1) + s->avctx->thread_count/2) / s->avctx->thread_count;
     }
 
de6d9b64
     return 0;
  fail:
8257bf05
     MPV_common_end(s);
de6d9b64
     return -1;
 }
 
 /* init common structure for both encoder and decoder */
 void MPV_common_end(MpegEncContext *s)
 {
bb198e19
     int i, j, k;
de6d9b64
 
9c3d33d6
     for(i=0; i<s->avctx->thread_count; i++){
         free_duplicate_context(s->thread_context[i]);
     }
     for(i=1; i<s->avctx->thread_count; i++){
         av_freep(&s->thread_context[i]);
     }
 
147e5200
     av_freep(&s->parse_context.buffer);
     s->parse_context.buffer_size=0;
 
6000abfa
     av_freep(&s->mb_type);
7bc9090a
     av_freep(&s->p_mv_table_base);
     av_freep(&s->b_forw_mv_table_base);
     av_freep(&s->b_back_mv_table_base);
     av_freep(&s->b_bidir_forw_mv_table_base);
     av_freep(&s->b_bidir_back_mv_table_base);
     av_freep(&s->b_direct_mv_table_base);
     s->p_mv_table= NULL;
     s->b_forw_mv_table= NULL;
     s->b_back_mv_table= NULL;
     s->b_bidir_forw_mv_table= NULL;
     s->b_bidir_back_mv_table= NULL;
     s->b_direct_mv_table= NULL;
bb198e19
     for(i=0; i<2; i++){
         for(j=0; j<2; j++){
             for(k=0; k<2; k++){
                 av_freep(&s->b_field_mv_table_base[i][j][k]);
                 s->b_field_mv_table[i][j][k]=NULL;
             }
             av_freep(&s->b_field_select_table[i][j]);
             av_freep(&s->p_field_mv_table_base[i][j]);
             s->p_field_mv_table[i][j]=NULL;
         }
         av_freep(&s->p_field_select_table[i]);
     }
115329f1
 
137c8468
     av_freep(&s->dc_val_base);
     av_freep(&s->ac_val_base);
     av_freep(&s->coded_block_base);
6000abfa
     av_freep(&s->mbintra_table);
7f2fe444
     av_freep(&s->cbp_table);
     av_freep(&s->pred_dir_table);
115329f1
 
6000abfa
     av_freep(&s->mbskip_table);
f943e138
     av_freep(&s->prev_pict_types);
6000abfa
     av_freep(&s->bitstream_buffer);
0ecca7a4
     s->allocated_bitstream_buffer_size=0;
 
3aa102be
     av_freep(&s->avctx->stats_out);
6b460aa3
     av_freep(&s->ac_stats);
4d2858de
     av_freep(&s->error_status_table);
7bc9090a
     av_freep(&s->mb_index2xy);
158c7f05
     av_freep(&s->lambda_table);
7e4995c3
     av_freep(&s->q_intra_matrix);
     av_freep(&s->q_inter_matrix);
642ccefb
     av_freep(&s->q_intra_matrix16);
     av_freep(&s->q_inter_matrix16);
9d9e3172
     av_freep(&s->input_picture);
     av_freep(&s->reordered_input_picture);
821cb11f
     av_freep(&s->dct_offset);
1e491e29
 
9b4b6e09
     if(s->picture){
         for(i=0; i<MAX_PICTURE_COUNT; i++){
             free_picture(s, &s->picture[i]);
         }
de6d9b64
     }
b465449e
     av_freep(&s->picture);
de6d9b64
     s->context_initialized = 0;
431f2172
     s->last_picture_ptr=
     s->next_picture_ptr=
     s->current_picture_ptr= NULL;
b100eab8
     s->linesize= s->uvlinesize= 0;
8100cab9
 
0c9bbaec
     for(i=0; i<3; i++)
8100cab9
         av_freep(&s->visualization_buffer[i]);
b100eab8
 
     avcodec_default_free_buffers(s->avctx);
de6d9b64
 }
 
3502a54f
 void init_rl(RLTable *rl, uint8_t static_store[2][2*MAX_RUN + MAX_LEVEL + 3])
1d0d55da
 {
0c1a9eda
     int8_t max_level[MAX_RUN+1], max_run[MAX_LEVEL+1];
     uint8_t index_run[MAX_RUN+1];
1d0d55da
     int last, run, level, start, end, i;
 
073c2593
     /* If table is static, we can quit if rl->max_level[0] is not NULL */
3502a54f
     if(static_store && rl->max_level[0])
073c2593
         return;
 
1d0d55da
     /* compute max_level[], max_run[] and index_run[] */
     for(last=0;last<2;last++) {
         if (last == 0) {
             start = 0;
             end = rl->last;
         } else {
             start = rl->last;
             end = rl->n;
         }
 
         memset(max_level, 0, MAX_RUN + 1);
         memset(max_run, 0, MAX_LEVEL + 1);
         memset(index_run, rl->n, MAX_RUN + 1);
         for(i=start;i<end;i++) {
             run = rl->table_run[i];
             level = rl->table_level[i];
             if (index_run[run] == rl->n)
                 index_run[run] = i;
             if (level > max_level[run])
                 max_level[run] = level;
             if (run > max_run[level])
                 max_run[level] = run;
         }
3502a54f
         if(static_store)
             rl->max_level[last] = static_store[last];
073c2593
         else
             rl->max_level[last] = av_malloc(MAX_RUN + 1);
1d0d55da
         memcpy(rl->max_level[last], max_level, MAX_RUN + 1);
3502a54f
         if(static_store)
             rl->max_run[last] = static_store[last] + MAX_RUN + 1;
073c2593
         else
             rl->max_run[last] = av_malloc(MAX_LEVEL + 1);
1d0d55da
         memcpy(rl->max_run[last], max_run, MAX_LEVEL + 1);
3502a54f
         if(static_store)
             rl->index_run[last] = static_store[last] + MAX_RUN + MAX_LEVEL + 2;
073c2593
         else
             rl->index_run[last] = av_malloc(MAX_RUN + 1);
1d0d55da
         memcpy(rl->index_run[last], index_run, MAX_RUN + 1);
     }
 }
 
ceaaf78b
 void init_vlc_rl(RLTable *rl)
898d5d5d
 {
     int i, q;
 
     for(q=0; q<32; q++){
         int qmul= q*2;
         int qadd= (q-1)|1;
 
         if(q==0){
             qmul=1;
             qadd=0;
         }
         for(i=0; i<rl->vlc.table_size; i++){
             int code= rl->vlc.table[i][0];
             int len = rl->vlc.table[i][1];
             int level, run;
 
             if(len==0){ // illegal code
                 run= 66;
                 level= MAX_LEVEL;
             }else if(len<0){ //more bits needed
                 run= 0;
                 level= code;
             }else{
                 if(code==rl->n){ //esc
                     run= 66;
                     level= 0;
                 }else{
                     run=   rl->table_run  [code] + 1;
                     level= rl->table_level[code] * qmul + qadd;
                     if(code >= rl->last) run+=192;
                 }
             }
             rl->rl_vlc[q][i].len= len;
             rl->rl_vlc[q][i].level= level;
             rl->rl_vlc[q][i].run= run;
         }
     }
 }
 
5f194811
 int ff_find_unused_picture(MpegEncContext *s, int shared){
4e00e76b
     int i;
115329f1
 
4e00e76b
     if(shared){
         for(i=0; i<MAX_PICTURE_COUNT; i++){
5f194811
             if(s->picture[i].data[0]==NULL && s->picture[i].type==0) return i;
4e00e76b
         }
     }else{
         for(i=0; i<MAX_PICTURE_COUNT; i++){
5f194811
             if(s->picture[i].data[0]==NULL && s->picture[i].type!=0) return i; //FIXME
4e00e76b
         }
         for(i=0; i<MAX_PICTURE_COUNT; i++){
5f194811
             if(s->picture[i].data[0]==NULL) return i;
4e00e76b
         }
     }
 
3c11a27b
     av_log(s->avctx, AV_LOG_FATAL, "Internal error, picture buffer overflow\n");
3a994ca4
     /* We could return -1, but the codec would crash trying to draw into a
      * non-existing frame anyway. This is safer than waiting for a random crash.
      * Also the return of this is never useful, an encoder must only allocate
      * as much as allowed in the specification. This has no relationship to how
      * much libavcodec could allocate (and MAX_PICTURE_COUNT is always large
      * enough for such valid streams).
      * Plus, a decoder has to check stream validity and remove frames if too
      * many reference frames are around. Waiting for "OOM" is not correct at
      * all. Similarly, missing reference frames have to be replaced by
      * interpolated/MC frames, anything else is a bug in the codec ...
      */
3c11a27b
     abort();
5f194811
     return -1;
4e00e76b
 }
 
821cb11f
 static void update_noise_reduction(MpegEncContext *s){
     int intra, i;
 
     for(intra=0; intra<2; intra++){
         if(s->dct_count[intra] > (1<<16)){
             for(i=0; i<64; i++){
                 s->dct_error_sum[intra][i] >>=1;
             }
             s->dct_count[intra] >>= 1;
         }
115329f1
 
821cb11f
         for(i=0; i<64; i++){
             s->dct_offset[intra][i]= (s->avctx->noise_reduction * s->dct_count[intra] + s->dct_error_sum[intra][i]/2) / (s->dct_error_sum[intra][i]+1);
         }
     }
 }
 
5f194811
 /**
  * generic function for encode/decode called after coding/decoding the header and before a frame is coded/decoded
  */
d6db1c9c
 int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
de6d9b64
 {
4e00e76b
     int i;
492cd3a9
     AVFrame *pic;
160d679c
     s->mb_skipped = 0;
0da71265
 
8b82a956
     assert(s->last_picture_ptr==NULL || s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3);
e20c4069
 
1e491e29
     /* mark&release old frames */
9701840b
     if (s->pict_type != FF_B_TYPE && s->last_picture_ptr && s->last_picture_ptr != s->next_picture_ptr && s->last_picture_ptr->data[0]) {
6ad7cd04
       if(s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3){
b536d0aa
         avctx->release_buffer(avctx, (AVFrame*)s->last_picture_ptr);
1e491e29
 
         /* release forgotten pictures */
         /* if(mpeg124/h263) */
         if(!s->encoding){
             for(i=0; i<MAX_PICTURE_COUNT; i++){
b536d0aa
                 if(s->picture[i].data[0] && &s->picture[i] != s->next_picture_ptr && s->picture[i].reference){
9b879566
                     av_log(avctx, AV_LOG_ERROR, "releasing zombie picture\n");
115329f1
                     avctx->release_buffer(avctx, (AVFrame*)&s->picture[i]);
1e491e29
                 }
             }
d6db1c9c
         }
6ad7cd04
       }
93a21abd
     }
aa388dba
 alloc:
     if(!s->encoding){
bb628dae
         /* release non reference frames */
e20c4069
         for(i=0; i<MAX_PICTURE_COUNT; i++){
             if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){
                 s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[i]);
             }
         }
 
5f194811
         if(s->current_picture_ptr && s->current_picture_ptr->data[0]==NULL)
bd107136
             pic= (AVFrame*)s->current_picture_ptr; //we already have a unused image (maybe it was set before reading the header)
5f194811
         else{
             i= ff_find_unused_picture(s, 0);
             pic= (AVFrame*)&s->picture[i];
         }
 
2ddcf84b
         pic->reference= 0;
         if (!s->dropable){
             if (s->codec_id == CODEC_ID_H264)
                 pic->reference = s->picture_structure;
9701840b
             else if (s->pict_type != FF_B_TYPE)
2ddcf84b
                 pic->reference = 3;
         }
b536d0aa
 
1031fabd
         pic->coded_picture_number= s->coded_picture_number++;
115329f1
 
f23a68df
         if( alloc_picture(s, (Picture*)pic, 0) < 0)
             return -1;
93a21abd
 
5f194811
         s->current_picture_ptr= (Picture*)pic;
c70f1716
         s->current_picture_ptr->top_field_first= s->top_field_first; //FIXME use only the vars from current_pic
2be9f03a
         s->current_picture_ptr->interlaced_frame= !s->progressive_frame && !s->progressive_sequence;
1e491e29
     }
b7adc711
 
9f2e61b6
     s->current_picture_ptr->pict_type= s->pict_type;
115329f1
 //    if(s->flags && CODEC_FLAG_QSCALE)
158c7f05
   //      s->current_picture_ptr->quality= s->new_picture_ptr->quality;
9701840b
     s->current_picture_ptr->key_frame= s->pict_type == FF_I_TYPE;
9f2e61b6
 
8d2fc163
     ff_copy_picture(&s->current_picture, s->current_picture_ptr);
115329f1
 
9701840b
     if (s->pict_type != FF_B_TYPE) {
b536d0aa
         s->last_picture_ptr= s->next_picture_ptr;
14e2a940
         if(!s->dropable)
             s->next_picture_ptr= s->current_picture_ptr;
de6d9b64
     }
14e2a940
 /*    av_log(s->avctx, AV_LOG_DEBUG, "L%p N%p C%p L%p N%p C%p type:%d drop:%d\n", s->last_picture_ptr, s->next_picture_ptr,s->current_picture_ptr,
115329f1
         s->last_picture_ptr    ? s->last_picture_ptr->data[0] : NULL,
         s->next_picture_ptr    ? s->next_picture_ptr->data[0] : NULL,
14e2a940
         s->current_picture_ptr ? s->current_picture_ptr->data[0] : NULL,
         s->pict_type, s->dropable);*/
115329f1
 
8d2fc163
     if(s->last_picture_ptr) ff_copy_picture(&s->last_picture, s->last_picture_ptr);
     if(s->next_picture_ptr) ff_copy_picture(&s->next_picture, s->next_picture_ptr);
115329f1
 
fe67a236
     if(s->pict_type != FF_I_TYPE && (s->last_picture_ptr==NULL || s->last_picture_ptr->data[0]==NULL) && !s->dropable && s->codec_id != CODEC_ID_H264){
9b879566
         av_log(avctx, AV_LOG_ERROR, "warning: first frame is no keyframe\n");
9701840b
         assert(s->pict_type != FF_B_TYPE); //these should have been dropped if we don't have a reference
ffba1dc0
         goto alloc;
     }
 
9701840b
     assert(s->pict_type == FF_I_TYPE || (s->last_picture_ptr && s->last_picture_ptr->data[0]));
ffba1dc0
 
12d96de3
     if(s->picture_structure!=PICT_FRAME && s->out_format != FMT_H264){
b536d0aa
         int i;
         for(i=0; i<4; i++){
             if(s->picture_structure == PICT_BOTTOM_FIELD){
                  s->current_picture.data[i] += s->current_picture.linesize[i];
115329f1
             }
b536d0aa
             s->current_picture.linesize[i] *= 2;
             s->last_picture.linesize[i] *=2;
             s->next_picture.linesize[i] *=2;
         }
     }
115329f1
 
aa388dba
     s->hurry_up= s->avctx->hurry_up;
047599a4
     s->error_recognition= avctx->error_recognition;
aa388dba
 
bb628dae
     /* set dequantizer, we can't do it during init as it might change for mpeg4
755bfeab
        and we can't do it in the header decode as init is not called for mpeg4 there yet */
d50635cd
     if(s->mpeg_quant || s->codec_id == CODEC_ID_MPEG2VIDEO){
         s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra;
         s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter;
ccff9da6
     }else if(s->out_format == FMT_H263 || s->out_format == FMT_H261){
d50635cd
         s->dct_unquantize_intra = s->dct_unquantize_h263_intra;
         s->dct_unquantize_inter = s->dct_unquantize_h263_inter;
     }else{
         s->dct_unquantize_intra = s->dct_unquantize_mpeg1_intra;
         s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter;
     }
d6db1c9c
 
821cb11f
     if(s->dct_error_sum){
         assert(s->avctx->noise_reduction && s->encoding);
 
         update_noise_reduction(s);
     }
115329f1
 
83344066
     if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
a002da79
         return ff_xvmc_field_start(s, avctx);
83344066
 
d6db1c9c
     return 0;
de6d9b64
 }
21af69f7
 
de6d9b64
 /* generic function for encode/decode called after a frame has been coded/decoded */
 void MPV_frame_end(MpegEncContext *s)
 {
1e491e29
     int i;
de6d9b64
     /* draw edge for correct motion prediction if outside */
38425603
     //just to make sure that all data is rendered.
83344066
     if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration){
a002da79
         ff_xvmc_field_end(s);
c269cf68
     }else if(!s->avctx->hwaccel
        && !(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
369122dd
        && s->unrestricted_mv
        && s->current_picture.reference
        && !s->intra_only
        && !(s->flags&CODEC_FLAG_EMU_EDGE)) {
5a6a9e78
             s->dsp.draw_edges(s->current_picture.data[0], s->linesize  , s->h_edge_pos   , s->v_edge_pos   , EDGE_WIDTH  );
             s->dsp.draw_edges(s->current_picture.data[1], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);
             s->dsp.draw_edges(s->current_picture.data[2], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);
de6d9b64
     }
5975626d
     emms_c();
115329f1
 
3aa102be
     s->last_pict_type    = s->pict_type;
88e51e1f
     s->last_lambda_for[s->pict_type]= s->current_picture_ptr->quality;
9701840b
     if(s->pict_type!=FF_B_TYPE){
8b4c7dbc
         s->last_non_b_pict_type= s->pict_type;
     }
b536d0aa
 #if 0
         /* copy back current_picture variables */
1e491e29
     for(i=0; i<MAX_PICTURE_COUNT; i++){
         if(s->picture[i].data[0] == s->current_picture.data[0]){
             s->picture[i]= s->current_picture;
             break;
115329f1
         }
1e491e29
     }
     assert(i<MAX_PICTURE_COUNT);
115329f1
 #endif
1e491e29
 
e20c4069
     if(s->encoding){
bb628dae
         /* release non-reference frames */
e20c4069
         for(i=0; i<MAX_PICTURE_COUNT; i++){
             if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){
                 s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[i]);
             }
         }
1e491e29
     }
b536d0aa
     // clear copies, to avoid confusion
 #if 0
     memset(&s->last_picture, 0, sizeof(Picture));
     memset(&s->next_picture, 0, sizeof(Picture));
     memset(&s->current_picture, 0, sizeof(Picture));
 #endif
7b37a6e9
     s->avctx->coded_frame= (AVFrame*)s->current_picture_ptr;
de6d9b64
 }
 
7bc9090a
 /**
db6e7795
  * draws an line from (ex, ey) -> (sx, sy).
  * @param w width of the image
  * @param h height of the image
  * @param stride stride/linesize of the image
  * @param color color of the arrow
  */
 static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, int w, int h, int stride, int color){
67eca72d
     int x, y, fr, f;
115329f1
 
f66e4f5f
     sx= av_clip(sx, 0, w-1);
     sy= av_clip(sy, 0, h-1);
     ex= av_clip(ex, 0, w-1);
     ey= av_clip(ey, 0, h-1);
115329f1
 
db6e7795
     buf[sy*stride + sx]+= color;
115329f1
 
c26abfa5
     if(FFABS(ex - sx) > FFABS(ey - sy)){
db6e7795
         if(sx > ex){
1345f4ed
             FFSWAP(int, sx, ex);
             FFSWAP(int, sy, ey);
db6e7795
         }
         buf+= sx + sy*stride;
         ex-= sx;
         f= ((ey-sy)<<16)/ex;
         for(x= 0; x <= ex; x++){
8100cab9
             y = (x*f)>>16;
             fr= (x*f)&0xFFFF;
             buf[ y   *stride + x]+= (color*(0x10000-fr))>>16;
             buf[(y+1)*stride + x]+= (color*         fr )>>16;
db6e7795
         }
     }else{
         if(sy > ey){
1345f4ed
             FFSWAP(int, sx, ex);
             FFSWAP(int, sy, ey);
db6e7795
         }
         buf+= sx + sy*stride;
         ey-= sy;
         if(ey) f= ((ex-sx)<<16)/ey;
         else   f= 0;
         for(y= 0; y <= ey; y++){
8100cab9
             x = (y*f)>>16;
             fr= (y*f)&0xFFFF;
cea96420
             buf[y*stride + x  ]+= (color*(0x10000-fr))>>16;
             buf[y*stride + x+1]+= (color*         fr )>>16;
db6e7795
         }
     }
 }
 
 /**
  * draws an arrow from (ex, ey) -> (sx, sy).
  * @param w width of the image
  * @param h height of the image
  * @param stride stride/linesize of the image
  * @param color color of the arrow
  */
115329f1
 static void draw_arrow(uint8_t *buf, int sx, int sy, int ex, int ey, int w, int h, int stride, int color){
db6e7795
     int dx,dy;
 
f66e4f5f
     sx= av_clip(sx, -100, w+100);
     sy= av_clip(sy, -100, h+100);
     ex= av_clip(ex, -100, w+100);
     ey= av_clip(ey, -100, h+100);
115329f1
 
db6e7795
     dx= ex - sx;
     dy= ey - sy;
115329f1
 
db6e7795
     if(dx*dx + dy*dy > 3*3){
         int rx=  dx + dy;
         int ry= -dx + dy;
         int length= ff_sqrt((rx*rx + ry*ry)<<8);
115329f1
 
db6e7795
         //FIXME subpixel accuracy
         rx= ROUNDED_DIV(rx*3<<4, length);
         ry= ROUNDED_DIV(ry*3<<4, length);
115329f1
 
db6e7795
         draw_line(buf, sx, sy, sx + rx, sy + ry, w, h, stride, color);
         draw_line(buf, sx, sy, sx - ry, sy + rx, w, h, stride, color);
     }
     draw_line(buf, sx, sy, ex, ey, w, h, stride, color);
 }
 
 /**
7bc9090a
  * prints debuging info for the given picture.
  */
0c9bbaec
 void ff_print_debug_info(MpegEncContext *s, AVFrame *pict){
7bc9090a
 
7f802534
     if(s->avctx->hwaccel) return;
7bc9090a
     if(!pict || !pict->mb_type) return;
 
     if(s->avctx->debug&(FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)){
         int x,y;
115329f1
 
0c9bbaec
         av_log(s->avctx,AV_LOG_DEBUG,"New frame, type: ");
         switch (pict->pict_type) {
             case FF_I_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"I\n"); break;
             case FF_P_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"P\n"); break;
             case FF_B_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"B\n"); break;
             case FF_S_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"S\n"); break;
             case FF_SI_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"SI\n"); break;
115329f1
             case FF_SP_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"SP\n"); break;
0c9bbaec
         }
7bc9090a
         for(y=0; y<s->mb_height; y++){
             for(x=0; x<s->mb_width; x++){
                 if(s->avctx->debug&FF_DEBUG_SKIP){
                     int count= s->mbskip_table[x + y*s->mb_stride];
                     if(count>9) count=9;
9b879566
                     av_log(s->avctx, AV_LOG_DEBUG, "%1d", count);
7bc9090a
                 }
                 if(s->avctx->debug&FF_DEBUG_QP){
9b879566
                     av_log(s->avctx, AV_LOG_DEBUG, "%2d", pict->qscale_table[x + y*s->mb_stride]);
7bc9090a
                 }
                 if(s->avctx->debug&FF_DEBUG_MB_TYPE){
                     int mb_type= pict->mb_type[x + y*s->mb_stride];
                     //Type & MV direction
                     if(IS_PCM(mb_type))
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, "P");
7bc9090a
                     else if(IS_INTRA(mb_type) && IS_ACPRED(mb_type))
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, "A");
7bc9090a
                     else if(IS_INTRA4x4(mb_type))
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, "i");
7bc9090a
                     else if(IS_INTRA16x16(mb_type))
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, "I");
7bc9090a
                     else if(IS_DIRECT(mb_type) && IS_SKIP(mb_type))
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, "d");
7bc9090a
                     else if(IS_DIRECT(mb_type))
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, "D");
7bc9090a
                     else if(IS_GMC(mb_type) && IS_SKIP(mb_type))
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, "g");
7bc9090a
                     else if(IS_GMC(mb_type))
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, "G");
7bc9090a
                     else if(IS_SKIP(mb_type))
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, "S");
7bc9090a
                     else if(!USES_LIST(mb_type, 1))
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, ">");
7bc9090a
                     else if(!USES_LIST(mb_type, 0))
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, "<");
7bc9090a
                     else{
                         assert(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1));
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, "X");
7bc9090a
                     }
115329f1
 
7bc9090a
                     //segmentation
                     if(IS_8X8(mb_type))
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, "+");
7bc9090a
                     else if(IS_16X8(mb_type))
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, "-");
7bc9090a
                     else if(IS_8X16(mb_type))
30344a83
                         av_log(s->avctx, AV_LOG_DEBUG, "|");
7bc9090a
                     else if(IS_INTRA(mb_type) || IS_16X16(mb_type))
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, " ");
7bc9090a
                     else
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, "?");
115329f1
 
 
7bc9090a
                     if(IS_INTERLACED(mb_type) && s->codec_id == CODEC_ID_H264)
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, "=");
7bc9090a
                     else
9b879566
                         av_log(s->avctx, AV_LOG_DEBUG, " ");
7bc9090a
                 }
9b879566
 //                av_log(s->avctx, AV_LOG_DEBUG, " ");
7bc9090a
             }
9b879566
             av_log(s->avctx, AV_LOG_DEBUG, "\n");
7bc9090a
         }
     }
8d7ec294
 
0c9bbaec
     if((s->avctx->debug&(FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) || (s->avctx->debug_mv)){
db6e7795
         const int shift= 1 + s->quarter_sample;
         int mb_y;
0c9bbaec
         uint8_t *ptr;
         int i;
014d2f05
         int h_chroma_shift, v_chroma_shift, block_height;
4f8a8319
         const int width = s->avctx->width;
         const int height= s->avctx->height;
650cec0c
         const int mv_sample_log2= 4 - pict->motion_subsample_log2;
c6f9e821
         const int mv_stride= (s->mb_width << mv_sample_log2) + (s->codec_id == CODEC_ID_H264 ? 0 : 1);
b846b231
         s->low_delay=0; //needed to see the vectors without trashing the buffers
0c9bbaec
 
0982834b
         avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift);
0c9bbaec
         for(i=0; i<3; i++){
4f8a8319
             memcpy(s->visualization_buffer[i], pict->data[i], (i==0) ? pict->linesize[i]*height:pict->linesize[i]*height >> v_chroma_shift);
0c9bbaec
             pict->data[i]= s->visualization_buffer[i];
         }
         pict->type= FF_BUFFER_TYPE_COPY;
         ptr= pict->data[0];
014d2f05
         block_height = 16>>v_chroma_shift;
db6e7795
 
         for(mb_y=0; mb_y<s->mb_height; mb_y++){
             int mb_x;
             for(mb_x=0; mb_x<s->mb_width; mb_x++){
                 const int mb_index= mb_x + mb_y*s->mb_stride;
0c9bbaec
                 if((s->avctx->debug_mv) && pict->motion_val){
                   int type;
                   for(type=0; type<3; type++){
e96682e6
                     int direction = 0;
0c9bbaec
                     switch (type) {
                       case 0: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_P_FOR)) || (pict->pict_type!=FF_P_TYPE))
                                 continue;
                               direction = 0;
                               break;
                       case 1: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_B_FOR)) || (pict->pict_type!=FF_B_TYPE))
                                 continue;
                               direction = 0;
                               break;
                       case 2: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_B_BACK)) || (pict->pict_type!=FF_B_TYPE))
                                 continue;
                               direction = 1;
                               break;
                     }
ae55b533
                     if(!USES_LIST(pict->mb_type[mb_index], direction))
                         continue;
 
0c9bbaec
                     if(IS_8X8(pict->mb_type[mb_index])){
                       int i;
                       for(i=0; i<4; i++){
db6e7795
                         int sx= mb_x*16 + 4 + 8*(i&1);
                         int sy= mb_y*16 + 4 + 8*(i>>1);
88730be6
                         int xy= (mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*mv_stride) << (mv_sample_log2-1);
0c9bbaec
                         int mx= (pict->motion_val[direction][xy][0]>>shift) + sx;
                         int my= (pict->motion_val[direction][xy][1]>>shift) + sy;
4f8a8319
                         draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100);
0c9bbaec
                       }
                     }else if(IS_16X8(pict->mb_type[mb_index])){
                       int i;
                       for(i=0; i<2; i++){
9bc8b386
                         int sx=mb_x*16 + 8;
                         int sy=mb_y*16 + 4 + 8*i;
88730be6
                         int xy= (mb_x*2 + (mb_y*2 + i)*mv_stride) << (mv_sample_log2-1);
650cec0c
                         int mx=(pict->motion_val[direction][xy][0]>>shift);
                         int my=(pict->motion_val[direction][xy][1]>>shift);
115329f1
 
650cec0c
                         if(IS_INTERLACED(pict->mb_type[mb_index]))
                             my*=2;
115329f1
 
650cec0c
                         draw_arrow(ptr, sx, sy, mx+sx, my+sy, width, height, s->linesize, 100);
                       }
                     }else if(IS_8X16(pict->mb_type[mb_index])){
                       int i;
                       for(i=0; i<2; i++){
                         int sx=mb_x*16 + 4 + 8*i;
                         int sy=mb_y*16 + 8;
88730be6
                         int xy= (mb_x*2 + i + mb_y*2*mv_stride) << (mv_sample_log2-1);
38030214
                         int mx=(pict->motion_val[direction][xy][0]>>shift);
                         int my=(pict->motion_val[direction][xy][1]>>shift);
115329f1
 
38030214
                         if(IS_INTERLACED(pict->mb_type[mb_index]))
                             my*=2;
115329f1
 
4f8a8319
                         draw_arrow(ptr, sx, sy, mx+sx, my+sy, width, height, s->linesize, 100);
0c9bbaec
                       }
                     }else{
                       int sx= mb_x*16 + 8;
                       int sy= mb_y*16 + 8;
650cec0c
                       int xy= (mb_x + mb_y*mv_stride) << mv_sample_log2;
0c9bbaec
                       int mx= (pict->motion_val[direction][xy][0]>>shift) + sx;
                       int my= (pict->motion_val[direction][xy][1]>>shift) + sy;
4f8a8319
                       draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100);
9bc8b386
                     }
115329f1
                   }
864119b6
                 }
                 if((s->avctx->debug&FF_DEBUG_VIS_QP) && pict->motion_val){
                     uint64_t c= (pict->qscale_table[mb_index]*128/31) * 0x0101010101010101ULL;
                     int y;
014d2f05
                     for(y=0; y<block_height; y++){
                         *(uint64_t*)(pict->data[1] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[1])= c;
                         *(uint64_t*)(pict->data[2] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[2])= c;
864119b6
                     }
                 }
                 if((s->avctx->debug&FF_DEBUG_VIS_MB_TYPE) && pict->motion_val){
                     int mb_type= pict->mb_type[mb_index];
                     uint64_t u,v;
                     int y;
 #define COLOR(theta, r)\
 u= (int)(128 + r*cos(theta*3.141592/180));\
 v= (int)(128 + r*sin(theta*3.141592/180));
 
115329f1
 
864119b6
                     u=v=128;
                     if(IS_PCM(mb_type)){
                         COLOR(120,48)
                     }else if((IS_INTRA(mb_type) && IS_ACPRED(mb_type)) || IS_INTRA16x16(mb_type)){
                         COLOR(30,48)
                     }else if(IS_INTRA4x4(mb_type)){
                         COLOR(90,48)
                     }else if(IS_DIRECT(mb_type) && IS_SKIP(mb_type)){
 //                        COLOR(120,48)
                     }else if(IS_DIRECT(mb_type)){
                         COLOR(150,48)
                     }else if(IS_GMC(mb_type) && IS_SKIP(mb_type)){
                         COLOR(170,48)
                     }else if(IS_GMC(mb_type)){
                         COLOR(190,48)
                     }else if(IS_SKIP(mb_type)){
 //                        COLOR(180,48)
                     }else if(!USES_LIST(mb_type, 1)){
                         COLOR(240,48)
                     }else if(!USES_LIST(mb_type, 0)){
                         COLOR(0,48)
                     }else{
                         assert(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1));
                         COLOR(300,48)
                     }
 
                     u*= 0x0101010101010101ULL;
                     v*= 0x0101010101010101ULL;
014d2f05
                     for(y=0; y<block_height; y++){
                         *(uint64_t*)(pict->data[1] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[1])= u;
                         *(uint64_t*)(pict->data[2] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[2])= v;
864119b6
                     }
 
                     //segmentation
                     if(IS_8X8(mb_type) || IS_16X8(mb_type)){
                         *(uint64_t*)(pict->data[0] + 16*mb_x + 0 + (16*mb_y + 8)*pict->linesize[0])^= 0x8080808080808080ULL;
                         *(uint64_t*)(pict->data[0] + 16*mb_x + 8 + (16*mb_y + 8)*pict->linesize[0])^= 0x8080808080808080ULL;
                     }
                     if(IS_8X8(mb_type) || IS_8X16(mb_type)){
                         for(y=0; y<16; y++)
                             pict->data[0][16*mb_x + 8 + (16*mb_y + y)*pict->linesize[0]]^= 0x80;
                     }
e21f3983
                     if(IS_8X8(mb_type) && mv_sample_log2 >= 2){
                         int dm= 1 << (mv_sample_log2-2);
                         for(i=0; i<4; i++){
                             int sx= mb_x*16 + 8*(i&1);
                             int sy= mb_y*16 + 8*(i>>1);
                             int xy= (mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*mv_stride) << (mv_sample_log2-1);
                             //FIXME bidir
                             int32_t *mv = (int32_t*)&pict->motion_val[0][xy];
                             if(mv[0] != mv[dm] || mv[dm*mv_stride] != mv[dm*(mv_stride+1)])
                                 for(y=0; y<8; y++)
                                     pict->data[0][sx + 4 + (sy + y)*pict->linesize[0]]^= 0x80;
                             if(mv[0] != mv[dm*mv_stride] || mv[dm] != mv[dm*(mv_stride+1)])
                                 *(uint64_t*)(pict->data[0] + sx + (sy + 4)*pict->linesize[0])^= 0x8080808080808080ULL;
                         }
                     }
115329f1
 
864119b6
                     if(IS_INTERLACED(mb_type) && s->codec_id == CODEC_ID_H264){
                         // hmm
                     }
db6e7795
                 }
                 s->mbskip_table[mb_index]=0;
             }
         }
     }
7bc9090a
 }
 
115329f1
 static inline int hpel_motion_lowres(MpegEncContext *s,
ac8b03c0
                                   uint8_t *dest, uint8_t *src,
                                   int field_based, int field_select,
                                   int src_x, int src_y,
                                   int width, int height, int stride,
                                   int h_edge_pos, int v_edge_pos,
                                   int w, int h, h264_chroma_mc_func *pix_op,
                                   int motion_x, int motion_y)
 {
     const int lowres= s->avctx->lowres;
     const int s_mask= (2<<lowres)-1;
     int emu=0;
     int sx, sy;
 
     if(s->quarter_sample){
         motion_x/=2;
         motion_y/=2;
     }
 
     sx= motion_x & s_mask;
     sy= motion_y & s_mask;
     src_x += motion_x >> (lowres+1);
     src_y += motion_y >> (lowres+1);
115329f1
 
ac8b03c0
     src += src_y * stride + src_x;
 
     if(   (unsigned)src_x > h_edge_pos                 - (!!sx) - w
        || (unsigned)src_y >(v_edge_pos >> field_based) - (!!sy) - h){
         ff_emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w+1, (h+1)<<field_based,
                             src_x, src_y<<field_based, h_edge_pos, v_edge_pos);
         src= s->edge_emu_buffer;
         emu=1;
     }
 
     sx <<= 2 - lowres;
     sy <<= 2 - lowres;
     if(field_select)
         src += s->linesize;
     pix_op[lowres](dest, src, stride, h, sx, sy);
     return emu;
 }
 
de6d9b64
 /* apply one mpeg motion vector to the three components */
849f1035
 static av_always_inline void mpeg_motion_lowres(MpegEncContext *s,
178fcca8
                                uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
                                int field_based, int bottom_field, int field_select,
                                uint8_t **ref_picture, h264_chroma_mc_func *pix_op,
                                int motion_x, int motion_y, int h)
 {
     uint8_t *ptr_y, *ptr_cb, *ptr_cr;
     int mx, my, src_x, src_y, uvsrc_x, uvsrc_y, uvlinesize, linesize, sx, sy, uvsx, uvsy;
     const int lowres= s->avctx->lowres;
     const int block_s= 8>>lowres;
     const int s_mask= (2<<lowres)-1;
     const int h_edge_pos = s->h_edge_pos >> lowres;
     const int v_edge_pos = s->v_edge_pos >> lowres;
     linesize   = s->current_picture.linesize[0] << field_based;
     uvlinesize = s->current_picture.linesize[1] << field_based;
 
ca74c0a1
     if(s->quarter_sample){ //FIXME obviously not perfect but qpel will not work in lowres anyway
da9c9637
         motion_x/=2;
         motion_y/=2;
     }
115329f1
 
da9c9637
     if(field_based){
         motion_y += (bottom_field - field_select)*((1<<lowres)-1);
     }
 
178fcca8
     sx= motion_x & s_mask;
     sy= motion_y & s_mask;
     src_x = s->mb_x*2*block_s               + (motion_x >> (lowres+1));
da9c9637
     src_y =(s->mb_y*2*block_s>>field_based) + (motion_y >> (lowres+1));
115329f1
 
178fcca8
     if (s->out_format == FMT_H263) {
71845595
         uvsx = ((motion_x>>1) & s_mask) | (sx&1);
         uvsy = ((motion_y>>1) & s_mask) | (sy&1);
178fcca8
         uvsrc_x = src_x>>1;
         uvsrc_y = src_y>>1;
     }else if(s->out_format == FMT_H261){//even chroma mv's are full pel in H261
         mx = motion_x / 4;
         my = motion_y / 4;
         uvsx = (2*mx) & s_mask;
         uvsy = (2*my) & s_mask;
         uvsrc_x = s->mb_x*block_s               + (mx >> lowres);
         uvsrc_y = s->mb_y*block_s               + (my >> lowres);
     } else {
         mx = motion_x / 2;
         my = motion_y / 2;
         uvsx = mx & s_mask;
         uvsy = my & s_mask;
         uvsrc_x = s->mb_x*block_s               + (mx >> (lowres+1));
da9c9637
         uvsrc_y =(s->mb_y*block_s>>field_based) + (my >> (lowres+1));
178fcca8
     }
 
     ptr_y  = ref_picture[0] + src_y * linesize + src_x;
     ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
     ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
 
     if(   (unsigned)src_x > h_edge_pos                 - (!!sx) - 2*block_s
        || (unsigned)src_y >(v_edge_pos >> field_based) - (!!sy) - h){
             ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, 17, 17+field_based,
                              src_x, src_y<<field_based, h_edge_pos, v_edge_pos);
             ptr_y = s->edge_emu_buffer;
49fb20cb
             if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
178fcca8
                 uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize;
115329f1
                 ff_emulated_edge_mc(uvbuf  , ptr_cb, s->uvlinesize, 9, 9+field_based,
178fcca8
                                  uvsrc_x, uvsrc_y<<field_based, h_edge_pos>>1, v_edge_pos>>1);
115329f1
                 ff_emulated_edge_mc(uvbuf+16, ptr_cr, s->uvlinesize, 9, 9+field_based,
178fcca8
                                  uvsrc_x, uvsrc_y<<field_based, h_edge_pos>>1, v_edge_pos>>1);
                 ptr_cb= uvbuf;
                 ptr_cr= uvbuf+16;
             }
     }
 
da9c9637
     if(bottom_field){ //FIXME use this for field pix too instead of the obnoxious hack which changes picture.data
         dest_y += s->linesize;
         dest_cb+= s->uvlinesize;
         dest_cr+= s->uvlinesize;
     }
 
     if(field_select){
         ptr_y += s->linesize;
         ptr_cb+= s->uvlinesize;
         ptr_cr+= s->uvlinesize;
     }
 
178fcca8
     sx <<= 2 - lowres;
     sy <<= 2 - lowres;
     pix_op[lowres-1](dest_y, ptr_y, linesize, h, sx, sy);
115329f1
 
49fb20cb
     if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
178fcca8
         uvsx <<= 2 - lowres;
         uvsy <<= 2 - lowres;
         pix_op[lowres](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy);
         pix_op[lowres](dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy);
     }
5f6c92d4
     //FIXME h261 lowres loop filter
178fcca8
 }
 
ac8b03c0
 static inline void chroma_4mv_motion_lowres(MpegEncContext *s,
                                      uint8_t *dest_cb, uint8_t *dest_cr,
                                      uint8_t **ref_picture,
                                      h264_chroma_mc_func *pix_op,
                                      int mx, int my){
     const int lowres= s->avctx->lowres;
     const int block_s= 8>>lowres;
     const int s_mask= (2<<lowres)-1;
     const int h_edge_pos = s->h_edge_pos >> (lowres+1);
     const int v_edge_pos = s->v_edge_pos >> (lowres+1);
     int emu=0, src_x, src_y, offset, sx, sy;
     uint8_t *ptr;
115329f1
 
ac8b03c0
     if(s->quarter_sample){
         mx/=2;
         my/=2;
     }
 
     /* In case of 8X8, we construct a single chroma motion vector
        with a special rounding */
     mx= ff_h263_round_chroma(mx);
     my= ff_h263_round_chroma(my);
115329f1
 
ac8b03c0
     sx= mx & s_mask;
     sy= my & s_mask;
     src_x = s->mb_x*block_s + (mx >> (lowres+1));
     src_y = s->mb_y*block_s + (my >> (lowres+1));
115329f1
 
ac8b03c0
     offset = src_y * s->uvlinesize + src_x;
     ptr = ref_picture[1] + offset;
     if(s->flags&CODEC_FLAG_EMU_EDGE){
         if(   (unsigned)src_x > h_edge_pos - (!!sx) - block_s
            || (unsigned)src_y > v_edge_pos - (!!sy) - block_s){
             ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, src_x, src_y, h_edge_pos, v_edge_pos);
             ptr= s->edge_emu_buffer;
             emu=1;
         }
115329f1
     }
ac8b03c0
     sx <<= 2 - lowres;
     sy <<= 2 - lowres;
     pix_op[lowres](dest_cb, ptr, s->uvlinesize, block_s, sx, sy);
115329f1
 
ac8b03c0
     ptr = ref_picture[2] + offset;
     if(emu){
         ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, src_x, src_y, h_edge_pos, v_edge_pos);
         ptr= s->edge_emu_buffer;
     }
     pix_op[lowres](dest_cr, ptr, s->uvlinesize, block_s, sx, sy);
 }
 
178fcca8
 /**
bb628dae
  * motion compensation of a single macroblock
178fcca8
  * @param s context
  * @param dest_y luma destination pointer
  * @param dest_cb chroma cb/u destination pointer
  * @param dest_cr chroma cr/v destination pointer
  * @param dir direction (0->forward, 1->backward)
  * @param ref_picture array[3] of pointers to the 3 planes of the reference picture
  * @param pic_op halfpel motion compensation function (average or put normally)
  * the motion vectors are taken from s->mv and the MV type from s->mv_type
  */
115329f1
 static inline void MPV_motion_lowres(MpegEncContext *s,
178fcca8
                               uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
115329f1
                               int dir, uint8_t **ref_picture,
178fcca8
                               h264_chroma_mc_func *pix_op)
 {
ac8b03c0
     int mx, my;
da9c9637
     int mb_x, mb_y, i;
     const int lowres= s->avctx->lowres;
115329f1
     const int block_s= 8>>lowres;
da9c9637
 
     mb_x = s->mb_x;
     mb_y = s->mb_y;
 
     switch(s->mv_type) {
     case MV_TYPE_16X16:
115329f1
         mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
da9c9637
                     0, 0, 0,
                     ref_picture, pix_op,
                     s->mv[dir][0][0], s->mv[dir][0][1], 2*block_s);
         break;
ac8b03c0
     case MV_TYPE_8X8:
da9c9637
         mx = 0;
         my = 0;
             for(i=0;i<4;i++) {
ac8b03c0
                 hpel_motion_lowres(s, dest_y + ((i & 1) + (i >> 1) * s->linesize)*block_s,
da9c9637
                             ref_picture[0], 0, 0,
ac8b03c0
                             (2*mb_x + (i & 1))*block_s, (2*mb_y + (i >>1))*block_s,
da9c9637
                             s->width, s->height, s->linesize,
ac8b03c0
                             s->h_edge_pos >> lowres, s->v_edge_pos >> lowres,
                             block_s, block_s, pix_op,
da9c9637
                             s->mv[dir][i][0], s->mv[dir][i][1]);
 
                 mx += s->mv[dir][i][0];
                 my += s->mv[dir][i][1];
             }
 
49fb20cb
         if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY))
ac8b03c0
             chroma_4mv_motion_lowres(s, dest_cb, dest_cr, ref_picture, pix_op, mx, my);
         break;
da9c9637
     case MV_TYPE_FIELD:
         if (s->picture_structure == PICT_FRAME) {
115329f1
             /* top field */
da9c9637
             mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
                         1, 0, s->field_select[dir][0],
                         ref_picture, pix_op,
                         s->mv[dir][0][0], s->mv[dir][0][1], block_s);
             /* bottom field */
             mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
                         1, 1, s->field_select[dir][1],
                         ref_picture, pix_op,
                         s->mv[dir][1][0], s->mv[dir][1][1], block_s);
         } else {
9701840b
             if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != FF_B_TYPE && !s->first_field){
da9c9637
                 ref_picture= s->current_picture_ptr->data;
115329f1
             }
da9c9637
 
             mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
                         0, 0, s->field_select[dir][0],
                         ref_picture, pix_op,
                         s->mv[dir][0][0], s->mv[dir][0][1], 2*block_s);
         }
         break;
     case MV_TYPE_16X8:
         for(i=0; i<2; i++){
             uint8_t ** ref2picture;
 
9701840b
             if(s->picture_structure == s->field_select[dir][i] + 1 || s->pict_type == FF_B_TYPE || s->first_field){
da9c9637
                 ref2picture= ref_picture;
             }else{
                 ref2picture= s->current_picture_ptr->data;
115329f1
             }
da9c9637
 
115329f1
             mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
da9c9637
                         0, 0, s->field_select[dir][i],
                         ref2picture, pix_op,
                         s->mv[dir][i][0], s->mv[dir][i][1] + 2*block_s*i, block_s);
115329f1
 
da9c9637
             dest_y += 2*block_s*s->linesize;
             dest_cb+= (2*block_s>>s->chroma_y_shift)*s->uvlinesize;
             dest_cr+= (2*block_s>>s->chroma_y_shift)*s->uvlinesize;
115329f1
         }
da9c9637
         break;
     case MV_TYPE_DMV:
         if(s->picture_structure == PICT_FRAME){
             for(i=0; i<2; i++){
                 int j;
                 for(j=0; j<2; j++){
                     mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
                                 1, j, j^i,
                                 ref_picture, pix_op,
                                 s->mv[dir][2*i + j][0], s->mv[dir][2*i + j][1], block_s);
                 }
                 pix_op = s->dsp.avg_h264_chroma_pixels_tab;
             }
         }else{
             for(i=0; i<2; i++){
115329f1
                 mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
da9c9637
                             0, 0, s->picture_structure != i+1,
                             ref_picture, pix_op,
                             s->mv[dir][2*i][0],s->mv[dir][2*i][1],2*block_s);
 
                 // after put we make avg of the same block
                 pix_op = s->dsp.avg_h264_chroma_pixels_tab;
 
                 //opposite parity is always in the same frame if this is second field
                 if(!s->first_field){
115329f1
                     ref_picture = s->current_picture_ptr->data;
da9c9637
                 }
             }
         }
     break;
     default: assert(0);
     }
178fcca8
 }
de6d9b64
 
 /* put block[] to dest[] */
115329f1
 static inline void put_dct(MpegEncContext *s,
6beeb962
                            DCTELEM *block, int i, uint8_t *dest, int line_size, int qscale)
de6d9b64
 {
d50635cd
     s->dct_unquantize_intra(s, block, i, qscale);
b0368839
     s->dsp.idct_put (dest, line_size, block);
de6d9b64
 }
 
 /* add block[] to dest[] */
115329f1
 static inline void add_dct(MpegEncContext *s,
0c1a9eda
                            DCTELEM *block, int i, uint8_t *dest, int line_size)
de6d9b64
 {
0f440e02
     if (s->block_last_index[i] >= 0) {
b0368839
         s->dsp.idct_add (dest, line_size, block);
0f440e02
     }
 }
2417652e
 
115329f1
 static inline void add_dequant_dct(MpegEncContext *s,
332f9ac4
                            DCTELEM *block, int i, uint8_t *dest, int line_size, int qscale)
0f440e02
 {
de6d9b64
     if (s->block_last_index[i] >= 0) {
d50635cd
         s->dct_unquantize_inter(s, block, i, qscale);
9dbcbd92
 
b0368839
         s->dsp.idct_add (dest, line_size, block);
de6d9b64
     }
 }
 
7f2fe444
 /**
  * cleans dc, ac, coded_block for the current non intra MB
  */
 void ff_clean_intra_table_entries(MpegEncContext *s)
 {
137c8468
     int wrap = s->b8_stride;
7f2fe444
     int xy = s->block_index[0];
115329f1
 
     s->dc_val[0][xy           ] =
     s->dc_val[0][xy + 1       ] =
7f2fe444
     s->dc_val[0][xy     + wrap] =
     s->dc_val[0][xy + 1 + wrap] = 1024;
     /* ac pred */
0c1a9eda
     memset(s->ac_val[0][xy       ], 0, 32 * sizeof(int16_t));
     memset(s->ac_val[0][xy + wrap], 0, 32 * sizeof(int16_t));
7f2fe444
     if (s->msmpeg4_version>=3) {
         s->coded_block[xy           ] =
         s->coded_block[xy + 1       ] =
         s->coded_block[xy     + wrap] =
         s->coded_block[xy + 1 + wrap] = 0;
     }
     /* chroma */
137c8468
     wrap = s->mb_stride;
     xy = s->mb_x + s->mb_y * wrap;
7f2fe444
     s->dc_val[1][xy] =
     s->dc_val[2][xy] = 1024;
     /* ac pred */
0c1a9eda
     memset(s->ac_val[1][xy], 0, 16 * sizeof(int16_t));
     memset(s->ac_val[2][xy], 0, 16 * sizeof(int16_t));
115329f1
 
137c8468
     s->mbintra_table[xy]= 0;
7f2fe444
 }
 
de6d9b64
 /* generic function called after a macroblock has been parsed by the
    decoder or after it has been encoded by the encoder.
 
    Important variables used:
    s->mb_intra : true if intra macroblock
    s->mv_dir   : motion vector direction
    s->mv_type  : motion vector type
    s->mv       : motion vector
    s->interlaced_dct : true if interlaced dct used (mpeg2)
  */
54816a3e
 static av_always_inline
 void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
bd7c626a
                             int lowres_flag, int is_mpeg12)
de6d9b64
 {
8257bf05
     int mb_x, mb_y;
7bc9090a
     const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
83344066
     if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration){
78f9a878
         ff_xvmc_decode_mb(s);//xvmc uses pblocks
2e7b4c84
         return;
     }
de6d9b64
 
     mb_x = s->mb_x;
     mb_y = s->mb_y;
 
8289c6fa
     if(s->avctx->debug&FF_DEBUG_DCT_COEFF) {
        /* save DCT coefficients */
        int i,j;
        DCTELEM *dct = &s->current_picture.dct_coeff[mb_xy*64*6];
        for(i=0; i<6; i++)
            for(j=0; j<64; j++)
                *dct++ = block[i][s->dsp.idct_permutation[j]];
     }
 
1e491e29
     s->current_picture.qscale_table[mb_xy]= s->qscale;
79e7b305
 
de6d9b64
     /* update DC predictors for P macroblocks */
     if (!s->mb_intra) {
bd7c626a
         if (!is_mpeg12 && (s->h263_pred || s->h263_aic)) {
0f440e02
             if(s->mbintra_table[mb_xy])
7f2fe444
                 ff_clean_intra_table_entries(s);
de6d9b64
         } else {
7f2fe444
             s->last_dc[0] =
             s->last_dc[1] =
de6d9b64
             s->last_dc[2] = 128 << s->intra_dc_precision;
         }
     }
bd7c626a
     else if (!is_mpeg12 && (s->h263_pred || s->h263_aic))
0f440e02
         s->mbintra_table[mb_xy]=1;
bff6ecaa
 
9701840b
     if ((s->flags&CODEC_FLAG_PSNR) || !(s->encoding && (s->intra_only || s->pict_type==FF_B_TYPE) && s->avctx->mb_decision != FF_MB_DECISION_RD)) { //FIXME precalc
0c1a9eda
         uint8_t *dest_y, *dest_cb, *dest_cr;
0f440e02
         int dct_linesize, dct_offset;
b3184779
         op_pixels_func (*op_pix)[4];
         qpel_mc_func (*op_qpix)[16];
dfb706da
         const int linesize= s->current_picture.linesize[0]; //not s->linesize as this would be wrong for field pics
b536d0aa
         const int uvlinesize= s->current_picture.linesize[1];
9701840b
         const int readable= s->pict_type != FF_B_TYPE || s->encoding || s->avctx->draw_horiz_band || lowres_flag;
178fcca8
         const int block_size= lowres_flag ? 8>>s->avctx->lowres : 8;
3bb4e23a
 
1e491e29
         /* avoid copy if macroblock skipped in last frame too */
         /* skip only during decoding as we might trash the buffers during encoding a bit */
         if(!s->encoding){
0c1a9eda
             uint8_t *mbskip_ptr = &s->mbskip_table[mb_xy];
1e491e29
             const int age= s->current_picture.age;
0fd90455
 
1e491e29
             assert(age);
 
160d679c
             if (s->mb_skipped) {
                 s->mb_skipped= 0;
9701840b
                 assert(s->pict_type!=FF_I_TYPE);
115329f1
 
160d679c
                 (*mbskip_ptr) ++; /* indicate that this time we skipped it */
0fd90455
                 if(*mbskip_ptr >99) *mbskip_ptr= 99;
 
1e491e29
                 /* if previous was skipped too, then nothing to do !  */
f943e138
                 if (*mbskip_ptr >= age && s->current_picture.reference){
                     return;
1e491e29
                 }
f943e138
             } else if(!s->current_picture.reference){
                 (*mbskip_ptr) ++; /* increase counter so the age can be compared cleanly */
                 if(*mbskip_ptr >99) *mbskip_ptr= 99;
             } else{
3bb4e23a
                 *mbskip_ptr = 0; /* not skipped */
             }
3994623d
         }
115329f1
 
ffdff4d7
         dct_linesize = linesize << s->interlaced_dct;
178fcca8
         dct_offset =(s->interlaced_dct)? linesize : linesize*block_size;
115329f1
 
b68ab260
         if(readable){
             dest_y=  s->dest[0];
             dest_cb= s->dest[1];
             dest_cr= s->dest[2];
         }else{
9c3d33d6
             dest_y = s->b_scratchpad;
ae35f5e1
             dest_cb= s->b_scratchpad+16*linesize;
ffdff4d7
             dest_cr= s->b_scratchpad+32*linesize;
b68ab260
         }
178fcca8
 
de6d9b64
         if (!s->mb_intra) {
             /* motion handling */
dfb706da
             /* decoding or more than one mb_type (MC was already done otherwise) */
7d1c3fc1
             if(!s->encoding){
178fcca8
                 if(lowres_flag){
                     h264_chroma_mc_func *op_pix = s->dsp.put_h264_chroma_pixels_tab;
de6d9b64
 
178fcca8
                     if (s->mv_dir & MV_DIR_FORWARD) {
                         MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix);
                         op_pix = s->dsp.avg_h264_chroma_pixels_tab;
                     }
                     if (s->mv_dir & MV_DIR_BACKWARD) {
                         MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix);
                     }
                 }else{
2833fc46
                     op_qpix= s->me.qpel_put;
9701840b
                     if ((!s->no_rounding) || s->pict_type==FF_B_TYPE){
178fcca8
                         op_pix = s->dsp.put_pixels_tab;
                     }else{
                         op_pix = s->dsp.put_no_rnd_pixels_tab;
                     }
                     if (s->mv_dir & MV_DIR_FORWARD) {
                         MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix, op_qpix);
                         op_pix = s->dsp.avg_pixels_tab;
2833fc46
                         op_qpix= s->me.qpel_avg;
178fcca8
                     }
                     if (s->mv_dir & MV_DIR_BACKWARD) {
                         MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix, op_qpix);
                     }
9dbcbd92
                 }
de6d9b64
             }
 
0f440e02
             /* skip dequant / idct if we are really late ;) */
8c3eba7c
             if(s->hurry_up>1) goto skip_idct;
             if(s->avctx->skip_idct){
9701840b
                 if(  (s->avctx->skip_idct >= AVDISCARD_NONREF && s->pict_type == FF_B_TYPE)
                    ||(s->avctx->skip_idct >= AVDISCARD_NONKEY && s->pict_type != FF_I_TYPE)
8c3eba7c
                    || s->avctx->skip_idct >= AVDISCARD_ALL)
                     goto skip_idct;
             }
0f440e02
 
de6d9b64
             /* add dct residue */
029911d1
             if(s->encoding || !(   s->h263_msmpeg4 || s->codec_id==CODEC_ID_MPEG1VIDEO || s->codec_id==CODEC_ID_MPEG2VIDEO
a0201736
                                 || (s->codec_id==CODEC_ID_MPEG4 && !s->mpeg_quant))){
178fcca8
                 add_dequant_dct(s, block[0], 0, dest_y                          , dct_linesize, s->qscale);
                 add_dequant_dct(s, block[1], 1, dest_y              + block_size, dct_linesize, s->qscale);
                 add_dequant_dct(s, block[2], 2, dest_y + dct_offset             , dct_linesize, s->qscale);
                 add_dequant_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale);
0f440e02
 
49fb20cb
                 if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
2d974017
                     if (s->chroma_y_shift){
                         add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale);
                         add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale);
                     }else{
                         dct_linesize >>= 1;
                         dct_offset >>=1;
                         add_dequant_dct(s, block[4], 4, dest_cb,              dct_linesize, s->chroma_qscale);
                         add_dequant_dct(s, block[5], 5, dest_cr,              dct_linesize, s->chroma_qscale);
                         add_dequant_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale);
                         add_dequant_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale);
                     }
b50eef3a
                 }
bd7c626a
             } else if(is_mpeg12 || (s->codec_id != CODEC_ID_WMV2)){
178fcca8
                 add_dct(s, block[0], 0, dest_y                          , dct_linesize);
                 add_dct(s, block[1], 1, dest_y              + block_size, dct_linesize);
                 add_dct(s, block[2], 2, dest_y + dct_offset             , dct_linesize);
                 add_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize);
de6d9b64
 
49fb20cb
                 if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
ffdff4d7
                     if(s->chroma_y_shift){//Chroma420
                         add_dct(s, block[4], 4, dest_cb, uvlinesize);
                         add_dct(s, block[5], 5, dest_cr, uvlinesize);
                     }else{
                         //chroma422
                         dct_linesize = uvlinesize << s->interlaced_dct;
                         dct_offset =(s->interlaced_dct)? uvlinesize : uvlinesize*8;
 
                         add_dct(s, block[4], 4, dest_cb, dct_linesize);
                         add_dct(s, block[5], 5, dest_cr, dct_linesize);
                         add_dct(s, block[6], 6, dest_cb+dct_offset, dct_linesize);
                         add_dct(s, block[7], 7, dest_cr+dct_offset, dct_linesize);
                         if(!s->chroma_x_shift){//Chroma444
                             add_dct(s, block[8], 8, dest_cb+8, dct_linesize);
                             add_dct(s, block[9], 9, dest_cr+8, dct_linesize);
                             add_dct(s, block[10], 10, dest_cb+8+dct_offset, dct_linesize);
                             add_dct(s, block[11], 11, dest_cr+8+dct_offset, dct_linesize);
                         }
                     }
                 }//fi gray
             }
49fb20cb
             else if (CONFIG_WMV2) {
1457ab52
                 ff_wmv2_add_mb(s, block, dest_y, dest_cb, dest_cr);
0f440e02
             }
de6d9b64
         } else {
             /* dct only in intra block */
029911d1
             if(s->encoding || !(s->codec_id==CODEC_ID_MPEG1VIDEO || s->codec_id==CODEC_ID_MPEG2VIDEO)){
178fcca8
                 put_dct(s, block[0], 0, dest_y                          , dct_linesize, s->qscale);
                 put_dct(s, block[1], 1, dest_y              + block_size, dct_linesize, s->qscale);
                 put_dct(s, block[2], 2, dest_y + dct_offset             , dct_linesize, s->qscale);
                 put_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale);
a0201736
 
49fb20cb
                 if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
2d974017
                     if(s->chroma_y_shift){
                         put_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale);
                         put_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale);
                     }else{
                         dct_offset >>=1;
                         dct_linesize >>=1;
                         put_dct(s, block[4], 4, dest_cb,              dct_linesize, s->chroma_qscale);
                         put_dct(s, block[5], 5, dest_cr,              dct_linesize, s->chroma_qscale);
                         put_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale);
                         put_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale);
                     }
a0201736
                 }
             }else{
178fcca8
                 s->dsp.idct_put(dest_y                          , dct_linesize, block[0]);
                 s->dsp.idct_put(dest_y              + block_size, dct_linesize, block[1]);
                 s->dsp.idct_put(dest_y + dct_offset             , dct_linesize, block[2]);
                 s->dsp.idct_put(dest_y + dct_offset + block_size, dct_linesize, block[3]);
a0201736
 
49fb20cb
                 if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
ffdff4d7
                     if(s->chroma_y_shift){
                         s->dsp.idct_put(dest_cb, uvlinesize, block[4]);
                         s->dsp.idct_put(dest_cr, uvlinesize, block[5]);
                     }else{
 
                         dct_linesize = uvlinesize << s->interlaced_dct;
                         dct_offset =(s->interlaced_dct)? uvlinesize : uvlinesize*8;
 
                         s->dsp.idct_put(dest_cb,              dct_linesize, block[4]);
                         s->dsp.idct_put(dest_cr,              dct_linesize, block[5]);
                         s->dsp.idct_put(dest_cb + dct_offset, dct_linesize, block[6]);
                         s->dsp.idct_put(dest_cr + dct_offset, dct_linesize, block[7]);
                         if(!s->chroma_x_shift){//Chroma444
                             s->dsp.idct_put(dest_cb + 8,              dct_linesize, block[8]);
                             s->dsp.idct_put(dest_cr + 8,              dct_linesize, block[9]);
                             s->dsp.idct_put(dest_cb + 8 + dct_offset, dct_linesize, block[10]);
                             s->dsp.idct_put(dest_cr + 8 + dct_offset, dct_linesize, block[11]);
                         }
                     }
                 }//gray
b50eef3a
             }
de6d9b64
         }
8c3eba7c
 skip_idct:
b68ab260
         if(!readable){
             s->dsp.put_pixels_tab[0][0](s->dest[0], dest_y ,   linesize,16);
ffdff4d7
             s->dsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[1], dest_cb, uvlinesize,16 >> s->chroma_y_shift);
             s->dsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[2], dest_cr, uvlinesize,16 >> s->chroma_y_shift);
b68ab260
         }
de6d9b64
     }
 }
 
178fcca8
 void MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]){
b250f9c6
 #if !CONFIG_SMALL
bd7c626a
     if(s->out_format == FMT_MPEG1) {
         if(s->avctx->lowres) MPV_decode_mb_internal(s, block, 1, 1);
         else                 MPV_decode_mb_internal(s, block, 0, 1);
     } else
 #endif
     if(s->avctx->lowres) MPV_decode_mb_internal(s, block, 1, 0);
     else                  MPV_decode_mb_internal(s, block, 0, 0);
178fcca8
 }
 
640950c7
 /**
  *
  * @param h is the normal height, this will be reduced automatically if needed for the last row
  */
 void ff_draw_horiz_band(MpegEncContext *s, int y, int h){
7a06ff14
     if (s->avctx->draw_horiz_band) {
3bb07d61
         AVFrame *src;
7a06ff14
         int offset[4];
115329f1
 
3bb07d61
         if(s->picture_structure != PICT_FRAME){
             h <<= 1;
             y <<= 1;
             if(s->first_field  && !(s->avctx->slice_flags&SLICE_FLAG_ALLOW_FIELD)) return;
         }
 
4f8a8319
         h= FFMIN(h, s->avctx->height - y);
4d2858de
 
9701840b
         if(s->pict_type==FF_B_TYPE || s->low_delay || (s->avctx->slice_flags&SLICE_FLAG_CODED_ORDER))
3bb07d61
             src= (AVFrame*)s->current_picture_ptr;
         else if(s->last_picture_ptr)
             src= (AVFrame*)s->last_picture_ptr;
         else
             return;
115329f1
 
9701840b
         if(s->pict_type==FF_B_TYPE && s->picture_structure == PICT_FRAME && s->out_format != FMT_H264){
7a06ff14
             offset[0]=
             offset[1]=
             offset[2]=
             offset[3]= 0;
         }else{
cea96420
             offset[0]= y * s->linesize;
115329f1
             offset[1]=
ffdff4d7
             offset[2]= (y >> s->chroma_y_shift) * s->uvlinesize;
7a06ff14
             offset[3]= 0;
4d2858de
         }
7a06ff14
 
0aa7875a
         emms_c();
 
3bb07d61
         s->avctx->draw_horiz_band(s->avctx, src, offset,
                                   y, s->picture_structure, h);
4d2858de
     }
 }
 
7d1c3fc1
 void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename
bb628dae
     const int linesize= s->current_picture.linesize[0]; //not s->linesize as this would be wrong for field pics
7d1c3fc1
     const int uvlinesize= s->current_picture.linesize[1];
178fcca8
     const int mb_size= 4 - s->avctx->lowres;
115329f1
 
137c8468
     s->block_index[0]= s->b8_stride*(s->mb_y*2    ) - 2 + s->mb_x*2;
     s->block_index[1]= s->b8_stride*(s->mb_y*2    ) - 1 + s->mb_x*2;
     s->block_index[2]= s->b8_stride*(s->mb_y*2 + 1) - 2 + s->mb_x*2;
     s->block_index[3]= s->b8_stride*(s->mb_y*2 + 1) - 1 + s->mb_x*2;
     s->block_index[4]= s->mb_stride*(s->mb_y + 1)                + s->b8_stride*s->mb_height*2 + s->mb_x - 1;
     s->block_index[5]= s->mb_stride*(s->mb_y + s->mb_height + 2) + s->b8_stride*s->mb_height*2 + s->mb_x - 1;
ffdff4d7
     //block_index is not used by mpeg2, so it is not affected by chroma_format
 
178fcca8
     s->dest[0] = s->current_picture.data[0] + ((s->mb_x - 1) << mb_size);
     s->dest[1] = s->current_picture.data[1] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift));
     s->dest[2] = s->current_picture.data[2] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift));
17659207
 
9701840b
     if(!(s->pict_type==FF_B_TYPE && s->avctx->draw_horiz_band && s->picture_structure==PICT_FRAME))
ffdff4d7
     {
178fcca8
         s->dest[0] += s->mb_y *   linesize << mb_size;
         s->dest[1] += s->mb_y * uvlinesize << (mb_size - s->chroma_y_shift);
         s->dest[2] += s->mb_y * uvlinesize << (mb_size - s->chroma_y_shift);
ffdff4d7
     }
7d1c3fc1
 }
 
7a06ff14
 void ff_mpeg_flush(AVCodecContext *avctx){
     int i;
     MpegEncContext *s = avctx->priv_data;
115329f1
 
     if(s==NULL || s->picture==NULL)
20f155ed
         return;
115329f1
 
7a06ff14
     for(i=0; i<MAX_PICTURE_COUNT; i++){
        if(s->picture[i].data[0] && (   s->picture[i].type == FF_BUFFER_TYPE_INTERNAL
                                     || s->picture[i].type == FF_BUFFER_TYPE_USER))
         avctx->release_buffer(avctx, (AVFrame*)&s->picture[i]);
     }
ea05d9c9
     s->current_picture_ptr = s->last_picture_ptr = s->next_picture_ptr = NULL;
115329f1
 
d0271e8a
     s->mb_x= s->mb_y= 0;
115329f1
 
769fc466
     s->parse_context.state= -1;
     s->parse_context.frame_start_found= 0;
     s->parse_context.overread= 0;
     s->parse_context.overread_index= 0;
     s->parse_context.index= 0;
     s->parse_context.last_index= 0;
ed263031
     s->bitstream_buffer_size=0;
2d0bcfb4
     s->pp_time=0;
7a06ff14
 }
 
115329f1
 static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
21af69f7
                                    DCTELEM *block, int n, int qscale)
de6d9b64
 {
badaf88e
     int i, level, nCoeffs;
0c1a9eda
     const uint16_t *quant_matrix;
de6d9b64
 
2ad1516a
     nCoeffs= s->block_last_index[n];
115329f1
 
     if (n < 4)
d50635cd
         block[0] = block[0] * s->y_dc_scale;
     else
         block[0] = block[0] * s->c_dc_scale;
     /* XXX: only mpeg1 */
     quant_matrix = s->intra_matrix;
     for(i=1;i<=nCoeffs;i++) {
         int j= s->intra_scantable.permutated[i];
         level = block[j];
         if (level) {
             if (level < 0) {
                 level = -level;
                 level = (int)(level * qscale * quant_matrix[j]) >> 3;
                 level = (level - 1) | 1;
                 level = -level;
             } else {
                 level = (int)(level * qscale * quant_matrix[j]) >> 3;
                 level = (level - 1) | 1;
de6d9b64
             }
d50635cd
             block[j] = level;
de6d9b64
         }
d50635cd
     }
 }
 
115329f1
 static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s,
d50635cd
                                    DCTELEM *block, int n, int qscale)
 {
     int i, level, nCoeffs;
     const uint16_t *quant_matrix;
 
     nCoeffs= s->block_last_index[n];
115329f1
 
d50635cd
     quant_matrix = s->inter_matrix;
     for(i=0; i<=nCoeffs; i++) {
         int j= s->intra_scantable.permutated[i];
         level = block[j];
         if (level) {
             if (level < 0) {
                 level = -level;
                 level = (((level << 1) + 1) * qscale *
                          ((int) (quant_matrix[j]))) >> 4;
                 level = (level - 1) | 1;
                 level = -level;
             } else {
                 level = (((level << 1) + 1) * qscale *
                          ((int) (quant_matrix[j]))) >> 4;
                 level = (level - 1) | 1;
de6d9b64
             }
d50635cd
             block[j] = level;
de6d9b64
         }
     }
 }
21af69f7
 
115329f1
 static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s,
9dbf1ddd
                                    DCTELEM *block, int n, int qscale)
 {
     int i, level, nCoeffs;
0c1a9eda
     const uint16_t *quant_matrix;
9dbf1ddd
 
2ad1516a
     if(s->alternate_scan) nCoeffs= 63;
     else nCoeffs= s->block_last_index[n];
115329f1
 
     if (n < 4)
d50635cd
         block[0] = block[0] * s->y_dc_scale;
     else
         block[0] = block[0] * s->c_dc_scale;
     quant_matrix = s->intra_matrix;
     for(i=1;i<=nCoeffs;i++) {
         int j= s->intra_scantable.permutated[i];
         level = block[j];
         if (level) {
             if (level < 0) {
                 level = -level;
                 level = (int)(level * qscale * quant_matrix[j]) >> 3;
                 level = -level;
             } else {
                 level = (int)(level * qscale * quant_matrix[j]) >> 3;
             }
             block[j] = level;
         }
     }
 }
 
e27b6e62
 static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s,
                                    DCTELEM *block, int n, int qscale)
 {
     int i, level, nCoeffs;
     const uint16_t *quant_matrix;
     int sum=-1;
 
     if(s->alternate_scan) nCoeffs= 63;
     else nCoeffs= s->block_last_index[n];
 
     if (n < 4)
         block[0] = block[0] * s->y_dc_scale;
     else
         block[0] = block[0] * s->c_dc_scale;
     quant_matrix = s->intra_matrix;
     for(i=1;i<=nCoeffs;i++) {
         int j= s->intra_scantable.permutated[i];
         level = block[j];
         if (level) {
             if (level < 0) {
                 level = -level;
                 level = (int)(level * qscale * quant_matrix[j]) >> 3;
                 level = -level;
             } else {
                 level = (int)(level * qscale * quant_matrix[j]) >> 3;
             }
             block[j] = level;
             sum+=level;
         }
     }
     block[63]^=sum&1;
 }
 
115329f1
 static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s,
d50635cd
                                    DCTELEM *block, int n, int qscale)
 {
     int i, level, nCoeffs;
     const uint16_t *quant_matrix;
     int sum=-1;
 
     if(s->alternate_scan) nCoeffs= 63;
     else nCoeffs= s->block_last_index[n];
115329f1
 
d50635cd
     quant_matrix = s->inter_matrix;
     for(i=0; i<=nCoeffs; i++) {
         int j= s->intra_scantable.permutated[i];
         level = block[j];
         if (level) {
             if (level < 0) {
                 level = -level;
                 level = (((level << 1) + 1) * qscale *
                          ((int) (quant_matrix[j]))) >> 4;
                 level = -level;
             } else {
                 level = (((level << 1) + 1) * qscale *
                          ((int) (quant_matrix[j]))) >> 4;
             }
             block[j] = level;
             sum+=level;
         }
     }
     block[63]^=sum&1;
 }
 
115329f1
 static void dct_unquantize_h263_intra_c(MpegEncContext *s,
d50635cd
                                   DCTELEM *block, int n, int qscale)
 {
     int i, level, qmul, qadd;
     int nCoeffs;
115329f1
 
d50635cd
     assert(s->block_last_index[n]>=0);
115329f1
 
d50635cd
     qmul = qscale << 1;
115329f1
 
d50635cd
     if (!s->h263_aic) {
115329f1
         if (n < 4)
9dbf1ddd
             block[0] = block[0] * s->y_dc_scale;
         else
             block[0] = block[0] * s->c_dc_scale;
d50635cd
         qadd = (qscale - 1) | 1;
     }else{
         qadd = 0;
     }
     if(s->ac_pred)
         nCoeffs=63;
     else
         nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
 
     for(i=1; i<=nCoeffs; i++) {
         level = block[i];
         if (level) {
             if (level < 0) {
                 level = level * qmul - qadd;
             } else {
                 level = level * qmul + qadd;
9dbf1ddd
             }
d50635cd
             block[i] = level;
9dbf1ddd
         }
     }
 }
 
115329f1
 static void dct_unquantize_h263_inter_c(MpegEncContext *s,
21af69f7
                                   DCTELEM *block, int n, int qscale)
 {
     int i, level, qmul, qadd;
badaf88e
     int nCoeffs;
115329f1
 
2ad1516a
     assert(s->block_last_index[n]>=0);
115329f1
 
2ad1516a
     qadd = (qscale - 1) | 1;
     qmul = qscale << 1;
115329f1
 
d50635cd
     nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
21af69f7
 
d50635cd
     for(i=0; i<=nCoeffs; i++) {
21af69f7
         level = block[i];
         if (level) {
             if (level < 0) {
                 level = level * qmul - qadd;
             } else {
                 level = level * qmul + qadd;
             }
             block[i] = level;
         }
     }
 }
de6d9b64
 
b776e3d1
 /**
  * set qscale and update qscale dependent variables.
  */
 void ff_set_qscale(MpegEncContext * s, int qscale)
 {
     if (qscale < 1)
         qscale = 1;
     else if (qscale > 31)
         qscale = 31;
 
     s->qscale = qscale;
     s->chroma_qscale= s->chroma_qscale_table[qscale];
 
     s->y_dc_scale= s->y_dc_scale_table[ qscale ];
     s->c_dc_scale= s->c_dc_scale_table[ s->chroma_qscale ];
 }