]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/msmpeg4.c
const
[ffmpeg] / libavcodec / msmpeg4.c
index ba58798e7da0edc2e5bbf444d06f8bf39e6dbb0d..8ca17c99d8f20dfb749f624ff1888d80fdd52e79 100644 (file)
@@ -3,6 +3,8 @@
  * Copyright (c) 2001 Fabrice Bellard.
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
+ * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at>
+ *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
@@ -18,8 +20,6 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at>
  */
 
 /**
@@ -30,6 +30,7 @@
 #include "avcodec.h"
 #include "dsputil.h"
 #include "mpegvideo.h"
+#include "msmpeg4.h"
 
 /*
  * You can also call this codec : MPEG4 with a twist !
@@ -42,7 +43,6 @@
 
 #define DC_VLC_BITS 9
 #define CBPY_VLC_BITS 6
-#define INTER_INTRA_VLC_BITS 3
 #define V1_INTRA_CBPC_VLC_BITS 6
 #define V1_INTER_CBPC_VLC_BITS 6
 #define V2_INTRA_CBPC_VLC_BITS 3
@@ -50,8 +50,6 @@
 #define MV_VLC_BITS 9
 #define V2_MV_VLC_BITS 9
 #define TEX_VLC_BITS 9
-#define MB_NON_INTRA_VLC_BITS 9
-#define MB_INTRA_VLC_BITS 9
 
 #define II_BITRATE 128*1024
 #define MBAC_BITRATE 50*1024
 static uint32_t v2_dc_lum_table[512][2];
 static uint32_t v2_dc_chroma_table[512][2];
 
-void ff_msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n);
-static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
-                                       int n, int coded, const uint8_t *scantable);
 static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr);
-static int msmpeg4_decode_motion(MpegEncContext * s,
-                                 int *mx_ptr, int *my_ptr);
 static void init_h263_dc_for_msmpeg4(void);
 static inline void msmpeg4_memsetw(short *tab, int val, int n);
 #ifdef CONFIG_ENCODERS
@@ -75,10 +68,9 @@ static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run,
 #endif //CONFIG_ENCODERS
 static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
 static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
-static int wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
 
 /* vc1 externs */
-extern uint8_t wmv3_dc_scale_table[32];
+extern const uint8_t wmv3_dc_scale_table[32];
 
 #ifdef DEBUG
 int intra_count = 0;
@@ -86,7 +78,6 @@ int frame_count = 0;
 #endif
 
 #include "msmpeg4data.h"
-#include "msmpeg4tab.h"
 
 #ifdef CONFIG_ENCODERS //strangely gcc includes this even if it is not references
 static uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2];
@@ -162,7 +153,7 @@ static void init_mv_table(MVTable *tab)
     }
 }
 
-void ff_code012(PutBitContext *pb, int n)
+void ff_msmpeg4_code012(PutBitContext *pb, int n)
 {
     if (n == 0) {
         put_bits(pb, 1, 0);
@@ -348,8 +339,8 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
 
         if(s->msmpeg4_version>2){
             if(!s->per_mb_rl_table){
-                ff_code012(&s->pb, s->rl_chroma_table_index);
-                ff_code012(&s->pb, s->rl_table_index);
+                ff_msmpeg4_code012(&s->pb, s->rl_chroma_table_index);
+                ff_msmpeg4_code012(&s->pb, s->rl_table_index);
             }
 
             put_bits(&s->pb, 1, s->dc_table_index);
@@ -362,7 +353,7 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
 
         if(s->msmpeg4_version>2){
             if(!s->per_mb_rl_table)
-                ff_code012(&s->pb, s->rl_table_index);
+                ff_msmpeg4_code012(&s->pb, s->rl_table_index);
 
             put_bits(&s->pb, 1, s->dc_table_index);
 
@@ -394,7 +385,7 @@ void msmpeg4_encode_ext_header(MpegEncContext * s)
 #endif //CONFIG_ENCODERS
 
 /* predict coded block */
-static inline int coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
+int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
 {
     int xy, wrap, pred, a, b, c;
 
@@ -422,7 +413,7 @@ static inline int coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_bl
 
 #ifdef CONFIG_ENCODERS
 
-static void msmpeg4_encode_motion(MpegEncContext * s,
+void ff_msmpeg4_encode_motion(MpegEncContext * s,
                                   int mx, int my)
 {
     int code;
@@ -460,7 +451,7 @@ static void msmpeg4_encode_motion(MpegEncContext * s,
     }
 }
 
-static inline void handle_slices(MpegEncContext *s){
+void ff_msmpeg4_handle_slices(MpegEncContext *s){
     if (s->mb_x == 0) {
         if (s->slice_height && (s->mb_y % s->slice_height) == 0) {
             if(s->msmpeg4_version < 4){
@@ -481,7 +472,7 @@ void msmpeg4_encode_mb(MpegEncContext * s,
     int pred_x, pred_y;
     uint8_t *coded_block;
 
-    handle_slices(s);
+    ff_msmpeg4_handle_slices(s);
 
     if (!s->mb_intra) {
         /* compute cbp */
@@ -527,7 +518,7 @@ void msmpeg4_encode_mb(MpegEncContext * s,
 
             /* motion vector */
             h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
-            msmpeg4_encode_motion(s, motion_x - pred_x,
+            ff_msmpeg4_encode_motion(s, motion_x - pred_x,
                                   motion_y - pred_y);
         }
 
@@ -547,7 +538,7 @@ void msmpeg4_encode_mb(MpegEncContext * s,
             cbp |= val << (5 - i);
             if (i < 4) {
                 /* predict value for close blocks only for luma */
-                pred = coded_block_pred(s, i, &coded_block);
+                pred = ff_msmpeg4_coded_block_pred(s, i, &coded_block);
                 *coded_block = val;
                 val = val ^ pred;
             }
@@ -883,7 +874,7 @@ void ff_msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n)
         } else {
             rl = &rl_table[3 + s->rl_chroma_table_index];
         }
-        run_diff = s->msmpeg4_version>=6;
+        run_diff = s->msmpeg4_version>=4;
         scantable= s->intra_scantable.permutated;
     } else {
         i = 0;
@@ -942,6 +933,9 @@ else
                     run1 = run - rl->max_run[last][level] - run_diff;
                     if (run1 < 0)
                         goto esc3;
+                    code = get_rl_index(rl, last, run1+1, level);
+                    if (s->msmpeg4_version == 4 && code == rl->n)
+                        goto esc3;
                     code = get_rl_index(rl, last, run1, level);
                     if (code == rl->n) {
                     esc3:
@@ -988,7 +982,7 @@ else
 /****************************************/
 /* decoding stuff */
 
-static VLC mb_non_intra_vlc[4];
+VLC ff_mb_non_intra_vlc[4];
 static VLC v2_dc_lum_vlc;
 static VLC v2_dc_chroma_vlc;
 static VLC cbpy_vlc;
@@ -997,7 +991,7 @@ static VLC v2_mb_type_vlc;
 static VLC v2_mv_vlc;
 static VLC v1_intra_cbpc_vlc;
 static VLC v1_inter_cbpc_vlc;
-static VLC inter_intra_vlc;
+VLC ff_inter_intra_vlc;
 
 /* This table is practically identical to the one from h263
  * except that it is inverted. */
@@ -1112,7 +1106,7 @@ int ff_msmpeg4_decode_init(MpegEncContext *s)
                  &mvtab[0][0], 2, 1, 1);
 
         for(i=0; i<4; i++){
-            init_vlc(&mb_non_intra_vlc[i], MB_NON_INTRA_VLC_BITS, 128,
+            init_vlc(&ff_mb_non_intra_vlc[i], MB_NON_INTRA_VLC_BITS, 128,
                      &wmv2_inter_table[i][0][1], 8, 4,
                      &wmv2_inter_table[i][0][0], 8, 4, 1); //FIXME name?
         }
@@ -1128,7 +1122,7 @@ int ff_msmpeg4_decode_init(MpegEncContext *s)
                  inter_MCBPC_bits, 1, 1,
                  inter_MCBPC_code, 1, 1, 1);
 
-        init_vlc(&inter_intra_vlc, INTER_INTRA_VLC_BITS, 4,
+        init_vlc(&ff_inter_intra_vlc, INTER_INTRA_VLC_BITS, 4,
                  &table_inter_intra[0][1], 2, 1,
                  &table_inter_intra[0][0], 2, 1, 1);
     }
@@ -1143,7 +1137,8 @@ int ff_msmpeg4_decode_init(MpegEncContext *s)
         s->decode_mb= msmpeg4v34_decode_mb;
         break;
     case 5:
-        s->decode_mb= wmv2_decode_mb;
+        if (ENABLE_WMV2_DECODER)
+            s->decode_mb= ff_wmv2_decode_mb;
     case 6:
         //FIXME + TODO VC1 decode mb
         break;
@@ -1506,7 +1501,7 @@ static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
 
     s->dsp.clear_blocks(s->block[0]);
     for (i = 0; i < 6; i++) {
-        if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
+        if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
         {
              av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
              return -1;
@@ -1539,7 +1534,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
             }
         }
 
-        code = get_vlc2(&s->gb, mb_non_intra_vlc[DEFAULT_INTER_INDEX].table, MB_NON_INTRA_VLC_BITS, 3);
+        code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[DEFAULT_INTER_INDEX].table, MB_NON_INTRA_VLC_BITS, 3);
         if (code < 0)
             return -1;
         //s->mb_intra = (code & 0x40) ? 0 : 1;
@@ -1556,7 +1551,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
         for(i=0;i<6;i++) {
             int val = ((code >> (5 - i)) & 1);
             if (i < 4) {
-                int pred = coded_block_pred(s, i, &coded_val);
+                int pred = ff_msmpeg4_coded_block_pred(s, i, &coded_val);
                 val = val ^ pred;
                 *coded_val = val;
             }
@@ -1572,7 +1567,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
             s->rl_chroma_table_index = s->rl_table_index;
         }
         h263_pred_motion(s, 0, 0, &mx, &my);
-        if (msmpeg4_decode_motion(s, &mx, &my) < 0)
+        if (ff_msmpeg4_decode_motion(s, &mx, &my) < 0)
             return -1;
         s->mv_dir = MV_DIR_FORWARD;
         s->mv_type = MV_TYPE_16X16;
@@ -1584,7 +1579,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
         s->ac_pred = get_bits1(&s->gb);
         *mb_type_ptr = MB_TYPE_INTRA;
         if(s->inter_intra_pred){
-            s->h263_aic_dir= get_vlc2(&s->gb, inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1);
+            s->h263_aic_dir= get_vlc2(&s->gb, ff_inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1);
 //            printf("%d%d %d %d/", s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y);
         }
         if(s->per_mb_rl_table && cbp){
@@ -1595,7 +1590,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
 
     s->dsp.clear_blocks(s->block[0]);
     for (i = 0; i < 6; i++) {
-        if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
+        if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
         {
             av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
             return -1;
@@ -1605,7 +1600,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
     return 0;
 }
 //#define ERROR_DETAILS
-static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
+int ff_msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
                               int n, int coded, const uint8_t *scan_table)
 {
     int level, i, last, run, run_diff;
@@ -1641,7 +1636,7 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
         }
         block[0] = level;
 
-        run_diff = 0;
+        run_diff = s->msmpeg4_version >= 4;
         i = 0;
         if (!coded) {
             goto not_coded;
@@ -1909,7 +1904,7 @@ static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
     return level;
 }
 
-static int msmpeg4_decode_motion(MpegEncContext * s,
+int ff_msmpeg4_decode_motion(MpegEncContext * s,
                                  int *mx_ptr, int *my_ptr)
 {
     MVTable *mv;
@@ -1947,9 +1942,3 @@ static int msmpeg4_decode_motion(MpegEncContext * s,
     *my_ptr = my;
     return 0;
 }
-
-/* cleanest way to support it
- * there is too much shared between versions so that we cant have 1 file per version & 1 common
- * as allmost everything would be in the common file
- */
-#include "wmv2.c"