rv34: export qp table
[ffmpeg.git] / libavcodec / mpegvideo_motion.c
index d4c4d6e..beb4d6c 100644 (file)
@@ -4,24 +4,27 @@
  *
  * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <string.h>
+
+#include "libavutil/avassert.h"
+#include "libavutil/internal.h"
 #include "avcodec.h"
 #include "dsputil.h"
 #include "mpegvideo.h"
@@ -29,9 +32,9 @@
 #include "msmpeg4.h"
 #include <limits.h>
 
-static inline void gmc1_motion(MpegEncContext *s,
-                               uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
-                               uint8_t **ref_picture)
+static void gmc1_motion(MpegEncContext *s,
+                        uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+                        uint8_t **ref_picture)
 {
     uint8_t *ptr;
     int offset, src_x, src_y, linesize, uvlinesize;
@@ -59,7 +62,7 @@ static inline void gmc1_motion(MpegEncContext *s,
     if(s->flags&CODEC_FLAG_EMU_EDGE){
         if(   (unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0)
            || (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)){
-            s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
             ptr= s->edge_emu_buffer;
         }
     }
@@ -72,9 +75,9 @@ static inline void gmc1_motion(MpegEncContext *s,
 
         dxy= ((motion_x>>3)&1) | ((motion_y>>2)&2);
         if (s->no_rounding){
-            s->dsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
+            s->hdsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
         }else{
-            s->dsp.put_pixels_tab       [0][dxy](dest_y, ptr, linesize, 16);
+            s->hdsp.put_pixels_tab       [0][dxy](dest_y, ptr, linesize, 16);
         }
     }
 
@@ -98,7 +101,7 @@ static inline void gmc1_motion(MpegEncContext *s,
     if(s->flags&CODEC_FLAG_EMU_EDGE){
         if(   (unsigned)src_x >= FFMAX((s->h_edge_pos>>1) - 9, 0)
            || (unsigned)src_y >= FFMAX((s->v_edge_pos>>1) - 9, 0)){
-            s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
             ptr= s->edge_emu_buffer;
             emu=1;
         }
@@ -107,7 +110,7 @@ static inline void gmc1_motion(MpegEncContext *s,
 
     ptr = ref_picture[2] + offset;
     if(emu){
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
         ptr= s->edge_emu_buffer;
     }
     s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
@@ -115,9 +118,9 @@ static inline void gmc1_motion(MpegEncContext *s,
     return;
 }
 
-static inline void gmc_motion(MpegEncContext *s,
-                               uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
-                               uint8_t **ref_picture)
+static void gmc_motion(MpegEncContext *s,
+                       uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+                       uint8_t **ref_picture)
 {
     uint8_t *ptr;
     int linesize, uvlinesize;
@@ -173,41 +176,35 @@ static inline void gmc_motion(MpegEncContext *s,
 
 static inline int hpel_motion(MpegEncContext *s,
                                   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, op_pixels_func *pix_op,
+                                  op_pixels_func *pix_op,
                                   int motion_x, int motion_y)
 {
-    int dxy;
+    int dxy = 0;
     int emu=0;
 
-    dxy = ((motion_y & 1) << 1) | (motion_x & 1);
     src_x += motion_x >> 1;
     src_y += motion_y >> 1;
 
     /* WARNING: do no forget half pels */
-    src_x = av_clip(src_x, -16, width); //FIXME unneeded for emu?
-    if (src_x == width)
-        dxy &= ~1;
-    src_y = av_clip(src_y, -16, height);
-    if (src_y == height)
-        dxy &= ~2;
-    src += src_y * stride + src_x;
+    src_x = av_clip(src_x, -16, s->width); //FIXME unneeded for emu?
+    if (src_x != s->width)
+        dxy |= motion_x & 1;
+    src_y = av_clip(src_y, -16, s->height);
+    if (src_y != s->height)
+        dxy |= (motion_y & 1) << 1;
+    src += src_y * s->linesize + src_x;
 
     if(s->unrestricted_mv && (s->flags&CODEC_FLAG_EMU_EDGE)){
-        if(   (unsigned)src_x > FFMAX(h_edge_pos - (motion_x&1) - w, 0)
-           || (unsigned)src_y > FFMAX(v_edge_pos - (motion_y&1) - h, 0)){
-            s->dsp.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, s->v_edge_pos);
+        if(   (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&1) - 8, 0)
+           || (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y&1) - 8, 0)){
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, 9, 9,
+                             src_x, src_y, s->h_edge_pos, s->v_edge_pos);
             src= s->edge_emu_buffer;
             emu=1;
         }
     }
-    if(field_select)
-        src += s->linesize;
-    pix_op[dxy](dest, src, stride, h);
+    pix_op[dxy](dest, src, s->linesize, 8);
     return emu;
 }
 
@@ -291,19 +288,19 @@ if(s->quarter_sample)
                         "MPEG motion vector out of boundary (%d %d)\n", src_x, src_y);
                 return;
             }
-            s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
                                 17, 17+field_based,
                                 src_x, src_y<<field_based,
                                 s->h_edge_pos, s->v_edge_pos);
             ptr_y = s->edge_emu_buffer;
             if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
                 uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize;
-                s->dsp.emulated_edge_mc(uvbuf ,
+                s->vdsp.emulated_edge_mc(uvbuf ,
                                     ptr_cb, s->uvlinesize,
                                     9, 9+field_based,
                                     uvsrc_x, uvsrc_y<<field_based,
                                     s->h_edge_pos>>1, s->v_edge_pos>>1);
-                s->dsp.emulated_edge_mc(uvbuf+16,
+                s->vdsp.emulated_edge_mc(uvbuf+16,
                                     ptr_cr, s->uvlinesize,
                                     9, 9+field_based,
                                     uvsrc_x, uvsrc_y<<field_based,
@@ -439,18 +436,16 @@ static inline void obmc_motion(MpegEncContext *s,
     int i;
     uint8_t *ptr[5];
 
-    assert(s->quarter_sample==0);
+    av_assert2(s->quarter_sample==0);
 
     for(i=0; i<5; i++){
         if(i && mv[i][0]==mv[MID][0] && mv[i][1]==mv[MID][1]){
             ptr[i]= ptr[MID];
         }else{
             ptr[i]= s->obmc_scratchpad + 8*(i&1) + s->linesize*8*(i>>1);
-            hpel_motion(s, ptr[i], src, 0, 0,
+            hpel_motion(s, ptr[i], src,
                         src_x, src_y,
-                        s->width, s->height, s->linesize,
-                        s->h_edge_pos, s->v_edge_pos,
-                        8, 8, pix_op,
+                        pix_op,
                         mv[i][0], mv[i][1]);
         }
     }
@@ -506,17 +501,17 @@ static inline void qpel_motion(MpegEncContext *s,
 
     if(   (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&3) - 16, 0)
        || (unsigned)src_y > FFMAX(   v_edge_pos - (motion_y&3) - h , 0)){
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
                             17, 17+field_based, src_x, src_y<<field_based,
                             s->h_edge_pos, s->v_edge_pos);
         ptr_y= s->edge_emu_buffer;
         if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
             uint8_t *uvbuf= s->edge_emu_buffer + 18*s->linesize;
-            s->dsp.emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize,
+            s->vdsp.emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize,
                                 9, 9 + field_based,
                                 uvsrc_x, uvsrc_y<<field_based,
                                 s->h_edge_pos>>1, s->v_edge_pos>>1);
-            s->dsp.emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize,
+            s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize,
                                 9, 9 + field_based,
                                 uvsrc_x, uvsrc_y<<field_based,
                                 s->h_edge_pos>>1, s->v_edge_pos>>1);
@@ -553,11 +548,12 @@ static inline void qpel_motion(MpegEncContext *s,
 /**
  * h263 chroma 4mv motion compensation.
  */
-static inline void chroma_4mv_motion(MpegEncContext *s,
-                                     uint8_t *dest_cb, uint8_t *dest_cr,
-                                     uint8_t **ref_picture,
-                                     op_pixels_func *pix_op,
-                                     int mx, int my){
+static void chroma_4mv_motion(MpegEncContext *s,
+                              uint8_t *dest_cb, uint8_t *dest_cr,
+                              uint8_t **ref_picture,
+                              op_pixels_func *pix_op,
+                              int mx, int my)
+{
     int dxy, emu=0, src_x, src_y, offset;
     uint8_t *ptr;
 
@@ -584,7 +580,7 @@ static inline void chroma_4mv_motion(MpegEncContext *s,
     if(s->flags&CODEC_FLAG_EMU_EDGE){
         if(   (unsigned)src_x > FFMAX((s->h_edge_pos>>1) - (dxy &1) - 8, 0)
            || (unsigned)src_y > FFMAX((s->v_edge_pos>>1) - (dxy>>1) - 8, 0)){
-            s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
                                 9, 9, src_x, src_y,
                                 s->h_edge_pos>>1, s->v_edge_pos>>1);
             ptr= s->edge_emu_buffer;
@@ -595,7 +591,7 @@ static inline void chroma_4mv_motion(MpegEncContext *s,
 
     ptr = ref_picture[2] + offset;
     if(emu){
-        s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
                             9, 9, src_x, src_y,
                             s->h_edge_pos>>1, s->v_edge_pos>>1);
         ptr= s->edge_emu_buffer;
@@ -610,9 +606,9 @@ static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir){
     const int mx= (s->mv[dir][0][0]>>shift) + 16*s->mb_x + 8;
     const int my= (s->mv[dir][0][1]>>shift) + 16*s->mb_y;
     int off= mx + (my + (s->mb_x&3)*4)*s->linesize + 64;
-    s->dsp.prefetch(pix[0]+off, s->linesize, 4);
+    s->vdsp.prefetch(pix[0]+off, s->linesize, 4);
     off= (mx>>1) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + 64;
-    s->dsp.prefetch(pix[1]+off, pix[2]-pix[1], 2);
+    s->vdsp.prefetch(pix[1]+off, pix[2]-pix[1], 2);
 }
 
 /**
@@ -644,37 +640,45 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s,
     prefetch_motion(s, ref_picture, dir);
 
     if(!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B){
-        int16_t mv_cache[4][4][2];
+        LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]);
+        Picture *cur_frame = &s->current_picture;
         const int xy= s->mb_x + s->mb_y*s->mb_stride;
         const int mot_stride= s->b8_stride;
         const int mot_xy= mb_x*2 + mb_y*2*mot_stride;
 
-        assert(!s->mb_skipped);
+        av_assert2(!s->mb_skipped);
+
+        AV_COPY32(mv_cache[1][1], cur_frame->motion_val[0][mot_xy    ]);
+        AV_COPY32(mv_cache[1][2], cur_frame->motion_val[0][mot_xy + 1]);
+
+        AV_COPY32(mv_cache[2][1], cur_frame->motion_val[0][mot_xy + mot_stride    ]);
+        AV_COPY32(mv_cache[2][2], cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
 
-        memcpy(mv_cache[1][1], s->current_picture.f.motion_val[0][mot_xy             ], sizeof(int16_t) * 4);
-        memcpy(mv_cache[2][1], s->current_picture.f.motion_val[0][mot_xy + mot_stride], sizeof(int16_t) * 4);
-        memcpy(mv_cache[3][1], s->current_picture.f.motion_val[0][mot_xy + mot_stride], sizeof(int16_t) * 4);
+        AV_COPY32(mv_cache[3][1], cur_frame->motion_val[0][mot_xy + mot_stride    ]);
+        AV_COPY32(mv_cache[3][2], cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
 
-        if (mb_y == 0 || IS_INTRA(s->current_picture.f.mb_type[xy - s->mb_stride])) {
-            memcpy(mv_cache[0][1], mv_cache[1][1], sizeof(int16_t)*4);
+        if (mb_y == 0 || IS_INTRA(cur_frame->mb_type[xy - s->mb_stride])) {
+            AV_COPY32(mv_cache[0][1], mv_cache[1][1]);
+            AV_COPY32(mv_cache[0][2], mv_cache[1][2]);
         }else{
-            memcpy(mv_cache[0][1], s->current_picture.f.motion_val[0][mot_xy - mot_stride], sizeof(int16_t) * 4);
+            AV_COPY32(mv_cache[0][1], cur_frame->motion_val[0][mot_xy - mot_stride    ]);
+            AV_COPY32(mv_cache[0][2], cur_frame->motion_val[0][mot_xy - mot_stride + 1]);
         }
 
-        if (mb_x == 0 || IS_INTRA(s->current_picture.f.mb_type[xy - 1])) {
+        if (mb_x == 0 || IS_INTRA(cur_frame->mb_type[xy - 1])) {
             AV_COPY32(mv_cache[1][0], mv_cache[1][1]);
             AV_COPY32(mv_cache[2][0], mv_cache[2][1]);
         }else{
-            AV_COPY32(mv_cache[1][0], s->current_picture.f.motion_val[0][mot_xy - 1]);
-            AV_COPY32(mv_cache[2][0], s->current_picture.f.motion_val[0][mot_xy - 1 + mot_stride]);
+            AV_COPY32(mv_cache[1][0], cur_frame->motion_val[0][mot_xy - 1]);
+            AV_COPY32(mv_cache[2][0], cur_frame->motion_val[0][mot_xy - 1 + mot_stride]);
         }
 
-        if (mb_x + 1 >= s->mb_width || IS_INTRA(s->current_picture.f.mb_type[xy + 1])) {
+        if (mb_x + 1 >= s->mb_width || IS_INTRA(cur_frame->mb_type[xy + 1])) {
             AV_COPY32(mv_cache[1][3], mv_cache[1][2]);
             AV_COPY32(mv_cache[2][3], mv_cache[2][2]);
         }else{
-            AV_COPY32(mv_cache[1][3], s->current_picture.f.motion_val[0][mot_xy + 2]);
-            AV_COPY32(mv_cache[2][3], s->current_picture.f.motion_val[0][mot_xy + 2 + mot_stride]);
+            AV_COPY32(mv_cache[1][3], cur_frame->motion_val[0][mot_xy + 2]);
+            AV_COPY32(mv_cache[2][3], cur_frame->motion_val[0][mot_xy + 2 + mot_stride]);
         }
 
         mx = 0;
@@ -756,7 +760,7 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s,
                 if(s->flags&CODEC_FLAG_EMU_EDGE){
                     if(   (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&3) - 8, 0)
                        || (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y&3) - 8, 0)){
-                        s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+                        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
                                             s->linesize, 9, 9,
                                             src_x, src_y,
                                             s->h_edge_pos, s->v_edge_pos);
@@ -772,11 +776,9 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s,
         }else{
             for(i=0;i<4;i++) {
                 hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
-                            ref_picture[0], 0, 0,
+                            ref_picture[0],
                             mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,
-                            s->width, s->height, s->linesize,
-                            s->h_edge_pos, s->v_edge_pos,
-                            8, 8, pix_op[1],
+                            pix_op[1],
                             s->mv[dir][i][0], s->mv[dir][i][1]);
 
                 mx += s->mv[dir][i][0];
@@ -851,7 +853,7 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s,
                                       s->mv[dir][2*i + j][0],
                                       s->mv[dir][2*i + j][1], 8, mb_y);
                 }
-                pix_op = s->dsp.avg_pixels_tab;
+                pix_op = s->hdsp.avg_pixels_tab;
             }
         }else{
             for(i=0; i<2; i++){
@@ -861,7 +863,7 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s,
                             s->mv[dir][2*i][0],s->mv[dir][2*i][1],16, mb_y>>1);
 
                 // after put we make avg of the same block
-                pix_op=s->dsp.avg_pixels_tab;
+                pix_op=s->hdsp.avg_pixels_tab;
 
                 //opposite parity is always in the same frame if this is second field
                 if(!s->first_field){
@@ -870,7 +872,7 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s,
             }
         }
     break;
-    default: assert(0);
+    default: av_assert2(0);
     }
 }