Browse code

MPEG-2 4:2:2 encoding support

Originally committed as revision 5387 to svn://svn.ffmpeg.org/ffmpeg/trunk

Baptiste Coudurier authored on 2006/05/17 00:19:54
Showing 4 changed files
... ...
@@ -45,6 +45,8 @@ version <next>
45 45
 - Smacker demuxer and decoder
46 46
 - NuppelVideo/MythTV demuxer and RTjpeg decoder
47 47
 - KMVC decoder
48
+- MPEG-2 intra vlc support
49
+- MPEG-2 4:2:2 encoder
48 50
 
49 51
 version 0.4.9-pre1:
50 52
 
... ...
@@ -232,6 +232,12 @@ static int encode_init(AVCodecContext *avctx)
232 232
         }
233 233
     }
234 234
 
235
+    if(avctx->profile == FF_PROFILE_UNKNOWN)
236
+        avctx->profile = s->chroma_format == CHROMA_420 ? 4 : 0;
237
+
238
+    if(avctx->level == FF_LEVEL_UNKNOWN)
239
+        avctx->level = s->chroma_format == CHROMA_420 ? 8 : 5;
240
+
235 241
     return 0;
236 242
 }
237 243
 
... ...
@@ -319,22 +325,14 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
319 319
             if(s->codec_id == CODEC_ID_MPEG2VIDEO){
320 320
                 put_header(s, EXT_START_CODE);
321 321
                 put_bits(&s->pb, 4, 1); //seq ext
322
-                put_bits(&s->pb, 1, 0); //esc
323 322
 
324
-                if(s->avctx->profile == FF_PROFILE_UNKNOWN){
325
-                    put_bits(&s->pb, 3, 4); //profile
326
-                }else{
327
-                    put_bits(&s->pb, 3, s->avctx->profile); //profile
328
-                }
323
+                put_bits(&s->pb, 1, s->chroma_format == CHROMA_422); //escx
329 324
 
330
-                if(s->avctx->level == FF_LEVEL_UNKNOWN){
331
-                    put_bits(&s->pb, 4, 8); //level
332
-                }else{
333
-                    put_bits(&s->pb, 4, s->avctx->level); //level
334
-                }
325
+                put_bits(&s->pb, 3, s->avctx->profile); //profile
326
+                put_bits(&s->pb, 4, s->avctx->level); //level
335 327
 
336 328
                 put_bits(&s->pb, 1, s->progressive_sequence);
337
-                put_bits(&s->pb, 2, 1); //chroma format 4:2:0
329
+                put_bits(&s->pb, 2, s->chroma_format);
338 330
                 put_bits(&s->pb, 2, 0); //horizontal size ext
339 331
                 put_bits(&s->pb, 2, 0); //vertical size ext
340 332
                 put_bits(&s->pb, 12, v>>18); //bitrate ext
... ...
@@ -468,7 +466,7 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
468 468
         put_bits(&s->pb, 1, s->alternate_scan);
469 469
         put_bits(&s->pb, 1, s->repeat_first_field);
470 470
         s->progressive_frame = s->progressive_sequence;
471
-        put_bits(&s->pb, 1, s->chroma_420_type=s->progressive_frame);
471
+        put_bits(&s->pb, 1, s->chroma_format == CHROMA_420 ? s->progressive_frame : 0); /* chroma_420_type */
472 472
         put_bits(&s->pb, 1, s->progressive_frame);
473 473
         put_bits(&s->pb, 1, 0); //composite_display_flag
474 474
     }
... ...
@@ -496,9 +494,10 @@ static inline void put_mb_modes(MpegEncContext *s, int n, int bits,
496 496
     }
497 497
 }
498 498
 
499
-void mpeg1_encode_mb(MpegEncContext *s,
500
-                     DCTELEM block[6][64],
501
-                     int motion_x, int motion_y)
499
+static always_inline void mpeg1_encode_mb_internal(MpegEncContext *s,
500
+                                                   DCTELEM block[6][64],
501
+                                                   int motion_x, int motion_y,
502
+                                                   int mb_block_count)
502 503
 {
503 504
     int i, cbp;
504 505
     const int mb_x = s->mb_x;
... ...
@@ -507,9 +506,9 @@ void mpeg1_encode_mb(MpegEncContext *s,
507 507
 
508 508
     /* compute cbp */
509 509
     cbp = 0;
510
-    for(i=0;i<6;i++) {
510
+    for(i=0;i<mb_block_count;i++) {
511 511
         if (s->block_last_index[i] >= 0)
512
-            cbp |= 1 << (5 - i);
512
+            cbp |= 1 << (mb_block_count - 1 - i);
513 513
     }
514 514
 
515 515
     if (cbp == 0 && !first_mb && s->mv_type == MV_TYPE_16X16 &&
... ...
@@ -615,8 +614,14 @@ void mpeg1_encode_mb(MpegEncContext *s,
615 615
                 }
616 616
                 s->mv_bits+= get_bits_diff(s);
617 617
             }
618
-            if(cbp)
619
-                put_bits(&s->pb, mbPatTable[cbp][1], mbPatTable[cbp][0]);
618
+            if(cbp) {
619
+                if (s->chroma_y_shift) {
620
+                    put_bits(&s->pb, mbPatTable[cbp][1], mbPatTable[cbp][0]);
621
+                } else {
622
+                    put_bits(&s->pb, mbPatTable[cbp>>2][1], mbPatTable[cbp>>2][0]);
623
+                    put_bits(&s->pb, 2, cbp & 3);
624
+                }
625
+            }
620 626
             s->f_count++;
621 627
         } else{
622 628
             static const int mb_type_len[4]={0,3,4,2}; //bak,for,bi
... ...
@@ -694,11 +699,17 @@ void mpeg1_encode_mb(MpegEncContext *s,
694 694
                 }
695 695
             }
696 696
             s->mv_bits += get_bits_diff(s);
697
-            if(cbp)
698
-                put_bits(&s->pb, mbPatTable[cbp][1], mbPatTable[cbp][0]);
697
+            if(cbp) {
698
+                if (s->chroma_y_shift) {
699
+                    put_bits(&s->pb, mbPatTable[cbp][1], mbPatTable[cbp][0]);
700
+                } else {
701
+                    put_bits(&s->pb, mbPatTable[cbp>>2][1], mbPatTable[cbp>>2][0]);
702
+                    put_bits(&s->pb, 2, cbp & 3);
703
+                }
704
+            }
699 705
         }
700
-        for(i=0;i<6;i++) {
701
-            if (cbp & (1 << (5 - i))) {
706
+        for(i=0;i<mb_block_count;i++) {
707
+            if (cbp & (1 << (mb_block_count - 1 - i))) {
702 708
                 mpeg1_encode_block(s, block[i], i);
703 709
             }
704 710
         }
... ...
@@ -710,6 +721,12 @@ void mpeg1_encode_mb(MpegEncContext *s,
710 710
     }
711 711
 }
712 712
 
713
+void mpeg1_encode_mb(MpegEncContext *s, DCTELEM block[6][64], int motion_x, int motion_y)
714
+{
715
+    if (s->chroma_format == CHROMA_420) mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 6);
716
+    else                                mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 8);
717
+}
718
+
713 719
 // RAL: Parameter added: f_or_b_code
714 720
 static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code)
715 721
 {
... ...
@@ -905,7 +922,7 @@ static void mpeg1_encode_block(MpegEncContext *s,
905 905
 
906 906
     /* DC coef */
907 907
     if (s->mb_intra) {
908
-        component = (n <= 3 ? 0 : n - 4 + 1);
908
+        component = (n <= 3 ? 0 : (n&1) + 1);
909 909
         dc = block[0]; /* overflow is impossible */
910 910
         diff = dc - s->last_dc[component];
911 911
         encode_dc(s, diff, component);
... ...
@@ -3249,7 +3266,7 @@ AVCodec mpeg2video_encoder = {
3249 3249
     MPV_encode_picture,
3250 3250
     MPV_encode_end,
3251 3251
     .supported_framerates= frame_rate_tab+1,
3252
-    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1},
3252
+    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, -1},
3253 3253
     .capabilities= CODEC_CAP_DELAY,
3254 3254
 };
3255 3255
 #endif
... ...
@@ -927,23 +927,39 @@ int MPV_encode_init(AVCodecContext *avctx)
927 927
 
928 928
     MPV_encode_defaults(s);
929 929
 
930
-    if(avctx->pix_fmt != PIX_FMT_YUVJ420P && avctx->pix_fmt != PIX_FMT_YUV420P){
931
-        av_log(avctx, AV_LOG_ERROR, "only YUV420 is supported\n");
932
-        return -1;
933
-    }
934
-
935
-    if(avctx->codec_id == CODEC_ID_MJPEG || avctx->codec_id == CODEC_ID_LJPEG){
936
-        if(avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL && avctx->pix_fmt != PIX_FMT_YUVJ420P){
930
+    switch (avctx->codec_id) {
931
+    case CODEC_ID_MPEG2VIDEO:
932
+        if(avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P){
933
+            av_log(avctx, AV_LOG_ERROR, "only YUV420 and YUV422 are supported\n");
934
+            return -1;
935
+        }
936
+        break;
937
+    case CODEC_ID_LJPEG:
938
+    case CODEC_ID_MJPEG:
939
+        if(avctx->pix_fmt != PIX_FMT_YUVJ420P && (avctx->pix_fmt != PIX_FMT_YUV420P || avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL)){
937 940
             av_log(avctx, AV_LOG_ERROR, "colorspace not supported in jpeg\n");
938 941
             return -1;
939 942
         }
940
-    }else{
941
-        if(avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL && avctx->pix_fmt != PIX_FMT_YUV420P){
942
-            av_log(avctx, AV_LOG_ERROR, "colorspace not supported\n");
943
+        break;
944
+    default:
945
+        if(avctx->pix_fmt != PIX_FMT_YUV420P){
946
+            av_log(avctx, AV_LOG_ERROR, "only YUV420 is supported\n");
943 947
             return -1;
944 948
         }
945 949
     }
946 950
 
951
+    switch (avctx->pix_fmt) {
952
+    case PIX_FMT_YUVJ422P:
953
+    case PIX_FMT_YUV422P:
954
+        s->chroma_format = CHROMA_422;
955
+        break;
956
+    case PIX_FMT_YUVJ420P:
957
+    case PIX_FMT_YUV420P:
958
+    default:
959
+        s->chroma_format = CHROMA_420;
960
+        break;
961
+    }
962
+
947 963
     s->bit_rate = avctx->bit_rate;
948 964
     s->width = avctx->width;
949 965
     s->height = avctx->height;
... ...
@@ -2466,11 +2482,6 @@ int MPV_encode_picture(AVCodecContext *avctx,
2466 2466
     AVFrame *pic_arg = data;
2467 2467
     int i, stuffing_count;
2468 2468
 
2469
-    if(avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUVJ420P){
2470
-        av_log(avctx, AV_LOG_ERROR, "this codec supports only YUV420P\n");
2471
-        return -1;
2472
-    }
2473
-
2474 2469
     for(i=0; i<avctx->thread_count; i++){
2475 2470
         int start_y= s->thread_context[i]->start_mb_y;
2476 2471
         int   end_y= s->thread_context[i]->  end_mb_y;
... ...
@@ -3968,8 +3979,17 @@ static always_inline void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM bloc
3968 3968
                 add_dequant_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale);
3969 3969
 
3970 3970
                 if(!(s->flags&CODEC_FLAG_GRAY)){
3971
-                    add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale);
3972
-                    add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale);
3971
+                    if (s->chroma_y_shift){
3972
+                        add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale);
3973
+                        add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale);
3974
+                    }else{
3975
+                        dct_linesize >>= 1;
3976
+                        dct_offset >>=1;
3977
+                        add_dequant_dct(s, block[4], 4, dest_cb,              dct_linesize, s->chroma_qscale);
3978
+                        add_dequant_dct(s, block[5], 5, dest_cr,              dct_linesize, s->chroma_qscale);
3979
+                        add_dequant_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale);
3980
+                        add_dequant_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale);
3981
+                    }
3973 3982
                 }
3974 3983
             } else if(s->codec_id != CODEC_ID_WMV2){
3975 3984
                 add_dct(s, block[0], 0, dest_y                          , dct_linesize);
... ...
@@ -4011,8 +4031,17 @@ static always_inline void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM bloc
4011 4011
                 put_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale);
4012 4012
 
4013 4013
                 if(!(s->flags&CODEC_FLAG_GRAY)){
4014
-                    put_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale);
4015
-                    put_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale);
4014
+                    if(s->chroma_y_shift){
4015
+                        put_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale);
4016
+                        put_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale);
4017
+                    }else{
4018
+                        dct_offset >>=1;
4019
+                        dct_linesize >>=1;
4020
+                        put_dct(s, block[4], 4, dest_cb,              dct_linesize, s->chroma_qscale);
4021
+                        put_dct(s, block[5], 5, dest_cr,              dct_linesize, s->chroma_qscale);
4022
+                        put_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale);
4023
+                        put_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale);
4024
+                    }
4016 4025
                 }
4017 4026
             }else{
4018 4027
                 s->dsp.idct_put(dest_y                          , dct_linesize, block[0]);
... ...
@@ -4234,19 +4263,19 @@ static void get_vissual_weight(int16_t *weight, uint8_t *ptr, int stride){
4234 4234
     }
4235 4235
 }
4236 4236
 
4237
-static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
4237
+static always_inline void encode_mb_internal(MpegEncContext *s, int motion_x, int motion_y, int mb_block_height, int mb_block_count)
4238 4238
 {
4239
-    int16_t weight[6][64];
4240
-    DCTELEM orig[6][64];
4239
+    int16_t weight[8][64];
4240
+    DCTELEM orig[8][64];
4241 4241
     const int mb_x= s->mb_x;
4242 4242
     const int mb_y= s->mb_y;
4243 4243
     int i;
4244
-    int skip_dct[6];
4244
+    int skip_dct[8];
4245 4245
     int dct_offset   = s->linesize*8; //default for progressive frames
4246 4246
     uint8_t *ptr_y, *ptr_cb, *ptr_cr;
4247 4247
     int wrap_y, wrap_c;
4248 4248
 
4249
-    for(i=0; i<6; i++) skip_dct[i]=0;
4249
+    for(i=0; i<mb_block_count; i++) skip_dct[i]=0;
4250 4250
 
4251 4251
     if(s->adaptive_quant){
4252 4252
         const int last_qp= s->qscale;
... ...
@@ -4282,16 +4311,16 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
4282 4282
     wrap_y = s->linesize;
4283 4283
     wrap_c = s->uvlinesize;
4284 4284
     ptr_y = s->new_picture.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16;
4285
-    ptr_cb = s->new_picture.data[1] + (mb_y * 8 * wrap_c) + mb_x * 8;
4286
-    ptr_cr = s->new_picture.data[2] + (mb_y * 8 * wrap_c) + mb_x * 8;
4285
+    ptr_cb = s->new_picture.data[1] + (mb_y * mb_block_height * wrap_c) + mb_x * 8;
4286
+    ptr_cr = s->new_picture.data[2] + (mb_y * mb_block_height * wrap_c) + mb_x * 8;
4287 4287
 
4288 4288
     if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){
4289 4289
         uint8_t *ebuf= s->edge_emu_buffer + 32;
4290 4290
         ff_emulated_edge_mc(ebuf            , ptr_y , wrap_y,16,16,mb_x*16,mb_y*16, s->width   , s->height);
4291 4291
         ptr_y= ebuf;
4292
-        ff_emulated_edge_mc(ebuf+18*wrap_y  , ptr_cb, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
4292
+        ff_emulated_edge_mc(ebuf+18*wrap_y  , ptr_cb, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
4293 4293
         ptr_cb= ebuf+18*wrap_y;
4294
-        ff_emulated_edge_mc(ebuf+18*wrap_y+8, ptr_cr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
4294
+        ff_emulated_edge_mc(ebuf+18*wrap_y+8, ptr_cr, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
4295 4295
         ptr_cr= ebuf+18*wrap_y+8;
4296 4296
     }
4297 4297
 
... ...
@@ -4311,6 +4340,8 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
4311 4311
 
4312 4312
                     dct_offset= wrap_y;
4313 4313
                     wrap_y<<=1;
4314
+                    if (s->chroma_format == CHROMA_422)
4315
+                        wrap_c<<=1;
4314 4316
                 }
4315 4317
             }
4316 4318
         }
... ...
@@ -4326,6 +4357,10 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
4326 4326
         }else{
4327 4327
             s->dsp.get_pixels(s->block[4], ptr_cb, wrap_c);
4328 4328
             s->dsp.get_pixels(s->block[5], ptr_cr, wrap_c);
4329
+            if(!s->chroma_y_shift){ /* 422 */
4330
+                s->dsp.get_pixels(s->block[6], ptr_cb + (dct_offset>>1), wrap_c);
4331
+                s->dsp.get_pixels(s->block[7], ptr_cr + (dct_offset>>1), wrap_c);
4332
+            }
4329 4333
         }
4330 4334
     }else{
4331 4335
         op_pixels_func (*op_pix)[4];
... ...
@@ -4371,6 +4406,8 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
4371 4371
 
4372 4372
                     dct_offset= wrap_y;
4373 4373
                     wrap_y<<=1;
4374
+                    if (s->chroma_format == CHROMA_422)
4375
+                        wrap_c<<=1;
4374 4376
                 }
4375 4377
             }
4376 4378
         }
... ...
@@ -4386,6 +4423,10 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
4386 4386
         }else{
4387 4387
             s->dsp.diff_pixels(s->block[4], ptr_cb, dest_cb, wrap_c);
4388 4388
             s->dsp.diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c);
4389
+            if(!s->chroma_y_shift){ /* 422 */
4390
+                s->dsp.diff_pixels(s->block[6], ptr_cb + (dct_offset>>1), dest_cb + (dct_offset>>1), wrap_c);
4391
+                s->dsp.diff_pixels(s->block[7], ptr_cr + (dct_offset>>1), dest_cr + (dct_offset>>1), wrap_c);
4392
+            }
4389 4393
         }
4390 4394
         /* pre quantization */
4391 4395
         if(s->current_picture.mc_mb_var[s->mb_stride*mb_y+ mb_x]<2*s->qscale*s->qscale){
... ...
@@ -4396,6 +4437,10 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
4396 4396
             if(s->dsp.sad[1](NULL, ptr_y +dct_offset+ 8, dest_y +dct_offset+ 8, wrap_y, 8) < 20*s->qscale) skip_dct[3]= 1;
4397 4397
             if(s->dsp.sad[1](NULL, ptr_cb              , dest_cb              , wrap_c, 8) < 20*s->qscale) skip_dct[4]= 1;
4398 4398
             if(s->dsp.sad[1](NULL, ptr_cr              , dest_cr              , wrap_c, 8) < 20*s->qscale) skip_dct[5]= 1;
4399
+            if(!s->chroma_y_shift){ /* 422 */
4400
+                if(s->dsp.sad[1](NULL, ptr_cb +(dct_offset>>1), dest_cb +(dct_offset>>1), wrap_c, 8) < 20*s->qscale) skip_dct[6]= 1;
4401
+                if(s->dsp.sad[1](NULL, ptr_cr +(dct_offset>>1), dest_cr +(dct_offset>>1), wrap_c, 8) < 20*s->qscale) skip_dct[7]= 1;
4402
+            }
4399 4403
         }
4400 4404
     }
4401 4405
 
... ...
@@ -4406,13 +4451,17 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
4406 4406
         if(!skip_dct[3]) get_vissual_weight(weight[3], ptr_y + dct_offset + 8, wrap_y);
4407 4407
         if(!skip_dct[4]) get_vissual_weight(weight[4], ptr_cb                , wrap_c);
4408 4408
         if(!skip_dct[5]) get_vissual_weight(weight[5], ptr_cr                , wrap_c);
4409
-        memcpy(orig[0], s->block[0], sizeof(DCTELEM)*64*6);
4409
+        if(!s->chroma_y_shift){ /* 422 */
4410
+            if(!skip_dct[6]) get_vissual_weight(weight[6], ptr_cb + (dct_offset>>1), wrap_c);
4411
+            if(!skip_dct[7]) get_vissual_weight(weight[7], ptr_cr + (dct_offset>>1), wrap_c);
4412
+        }
4413
+        memcpy(orig[0], s->block[0], sizeof(DCTELEM)*64*mb_block_count);
4410 4414
     }
4411 4415
 
4412 4416
     /* DCT & quantize */
4413 4417
     assert(s->out_format!=FMT_MJPEG || s->qscale==8);
4414 4418
     {
4415
-        for(i=0;i<6;i++) {
4419
+        for(i=0;i<mb_block_count;i++) {
4416 4420
             if(!skip_dct[i]){
4417 4421
                 int overflow;
4418 4422
                 s->block_last_index[i] = s->dct_quantize(s, s->block[i], i, s->qscale, &overflow);
... ...
@@ -4424,7 +4473,7 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
4424 4424
                 s->block_last_index[i]= -1;
4425 4425
         }
4426 4426
         if(s->avctx->quantizer_noise_shaping){
4427
-            for(i=0;i<6;i++) {
4427
+            for(i=0;i<mb_block_count;i++) {
4428 4428
                 if(!skip_dct[i]){
4429 4429
                     s->block_last_index[i] = dct_quantize_refine(s, s->block[i], weight[i], orig[i], i, s->qscale);
4430 4430
                 }
... ...
@@ -4435,11 +4484,11 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
4435 4435
             for(i=0; i<4; i++)
4436 4436
                 dct_single_coeff_elimination(s, i, s->luma_elim_threshold);
4437 4437
         if(s->chroma_elim_threshold && !s->mb_intra)
4438
-            for(i=4; i<6; i++)
4438
+            for(i=4; i<mb_block_count; i++)
4439 4439
                 dct_single_coeff_elimination(s, i, s->chroma_elim_threshold);
4440 4440
 
4441 4441
         if(s->flags & CODEC_FLAG_CBP_RD){
4442
-            for(i=0;i<6;i++) {
4442
+            for(i=0;i<mb_block_count;i++) {
4443 4443
                 if(s->block_last_index[i] == -1)
4444 4444
                     s->coded_score[i]= INT_MAX/256;
4445 4445
             }
... ...
@@ -4455,7 +4504,7 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
4455 4455
 
4456 4456
     //non c quantize code returns incorrect block_last_index FIXME
4457 4457
     if(s->alternate_scan && s->dct_quantize != dct_quantize_c){
4458
-        for(i=0; i<6; i++){
4458
+        for(i=0; i<mb_block_count; i++){
4459 4459
             int j;
4460 4460
             if(s->block_last_index[i]>0){
4461 4461
                 for(j=63; j>0; j--){
... ...
@@ -4496,6 +4545,12 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
4496 4496
     }
4497 4497
 }
4498 4498
 
4499
+static always_inline void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
4500
+{
4501
+    if (s->chroma_format == CHROMA_420) encode_mb_internal(s, motion_x, motion_y,  8, 6);
4502
+    else                                encode_mb_internal(s, motion_x, motion_y, 16, 8);
4503
+}
4504
+
4499 4505
 #endif //CONFIG_ENCODERS
4500 4506
 
4501 4507
 void ff_mpeg_flush(AVCodecContext *avctx){
... ...
@@ -4605,7 +4660,7 @@ static inline void copy_context_after_encode(MpegEncContext *d, MpegEncContext *
4605 4605
         d->tex_pb= s->tex_pb;
4606 4606
     }
4607 4607
     d->block= s->block;
4608
-    for(i=0; i<6; i++)
4608
+    for(i=0; i<8; i++)
4609 4609
         d->block_last_index[i]= s->block_last_index[i];
4610 4610
     d->interlaced_dct= s->interlaced_dct;
4611 4611
     d->qscale= s->qscale;
... ...
@@ -486,7 +486,7 @@ typedef struct MpegEncContext {
486 486
     uint8_t *chroma_dc_vlc_length;
487 487
 #define UNI_AC_ENC_INDEX(run,level) ((run)*128 + (level))
488 488
 
489
-    int coded_score[6];
489
+    int coded_score[8];
490 490
 
491 491
     /** precomputed matrix (combine qscale and DCT renorm) */
492 492
     int (*q_intra_matrix)[64];