]> git.sesse.net Git - x264/blobdiff - common/frame.c
Deduplicate the ALIGN macro, move it to common.h
[x264] / common / frame.c
index cf36c5d7639b979ea807c64413be9d975ab23018..b589266f307ce369af56409425ab47edc1f64d54 100644 (file)
@@ -24,8 +24,6 @@
 
 #include "common.h"
 
-#define ALIGN(x,a) (((x)+((a)-1))&~((a)-1))
-
 x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
 {
     x264_frame_t *frame;
@@ -40,9 +38,9 @@ x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
     CHECKED_MALLOCZERO( frame, sizeof(x264_frame_t) );
 
     /* allocate frame data (+64 for extra data for me) */
-    i_width  = ALIGN( h->param.i_width, 16 );
+    i_width  = h->sps->i_mb_width*16;
     i_stride = ALIGN( i_width + 2*PADH, align );
-    i_lines  = ALIGN( h->param.i_height, 16<<h->param.b_interlaced );
+    i_lines  = h->sps->i_mb_height*16;
 
     frame->i_plane = 3;
     for( int i = 0; i < 3; i++ )
@@ -56,7 +54,7 @@ x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
     chroma_plane_size = (frame->i_stride[1] * (frame->i_lines[1] + 2*i_padv));
     for( int i = 1; i < 3; i++ )
     {
-        CHECKED_MALLOC( frame->buffer[i], chroma_plane_size );
+        CHECKED_MALLOC( frame->buffer[i], chroma_plane_size * sizeof(pixel) );
         frame->plane[i] = frame->buffer[i] + (frame->i_stride[i] * i_padv + PADH)/2;
     }
 
@@ -87,14 +85,14 @@ x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
      * requires them to be in-phase wrt cacheline alignment. */
     if( h->param.analyse.i_subpel_refine && b_fdec )
     {
-        CHECKED_MALLOC( frame->buffer[0], 4*luma_plane_size );
+        CHECKED_MALLOC( frame->buffer[0], 4*luma_plane_size * sizeof(pixel) );
         for( int i = 0; i < 4; i++ )
             frame->filtered[i] = frame->buffer[0] + i*luma_plane_size + frame->i_stride[0] * i_padv + PADH;
         frame->plane[0] = frame->filtered[0];
     }
     else
     {
-        CHECKED_MALLOC( frame->buffer[0], luma_plane_size );
+        CHECKED_MALLOC( frame->buffer[0], luma_plane_size * sizeof(pixel) );
         frame->filtered[0] = frame->plane[0] = frame->buffer[0] + frame->i_stride[0] * i_padv + PADH;
     }
 
@@ -105,6 +103,7 @@ x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
         CHECKED_MALLOC( frame->mb_type, i_mb_count * sizeof(int8_t));
         CHECKED_MALLOC( frame->mb_partition, i_mb_count * sizeof(uint8_t));
         CHECKED_MALLOC( frame->mv[0], 2*16 * i_mb_count * sizeof(int16_t) );
+        CHECKED_MALLOC( frame->mv16x16, 2*i_mb_count * sizeof(int16_t) );
         CHECKED_MALLOC( frame->ref[0], 4 * i_mb_count * sizeof(int8_t) );
         if( h->param.i_bframe )
         {
@@ -117,7 +116,7 @@ x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
             frame->ref[1] = NULL;
         }
         CHECKED_MALLOC( frame->i_row_bits, i_lines/16 * sizeof(int) );
-        CHECKED_MALLOC( frame->i_row_qp, i_lines/16 * sizeof(int) );
+        CHECKED_MALLOC( frame->f_row_qp, i_lines/16 * sizeof(float) );
         if( h->param.analyse.i_me_method >= X264_ME_ESA )
         {
             CHECKED_MALLOC( frame->buffer[3],
@@ -135,7 +134,7 @@ x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
 
             luma_plane_size = frame->i_stride_lowres * (frame->i_lines[0]/2 + 2*PADV);
 
-            CHECKED_MALLOC( frame->buffer_lowres[0], 4 * luma_plane_size );
+            CHECKED_MALLOC( frame->buffer_lowres[0], 4 * luma_plane_size * sizeof(pixel) );
             for( int i = 0; i < 4; i++ )
                 frame->lowres[i] = frame->buffer_lowres[0] + (frame->i_stride_lowres * PADV + PADH) + i * luma_plane_size;
 
@@ -148,10 +147,7 @@ x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
             CHECKED_MALLOC( frame->i_propagate_cost, (i_mb_count+3) * sizeof(uint16_t) );
             for( int j = 0; j <= h->param.i_bframe+1; j++ )
                 for( int i = 0; i <= h->param.i_bframe+1; i++ )
-                {
                     CHECKED_MALLOC( frame->lowres_costs[j][i], (i_mb_count+3) * sizeof(uint16_t) );
-                    CHECKED_MALLOC( frame->lowres_inter_types[j][i], (i_mb_count+3)/4 * sizeof(uint8_t) );
-                }
             frame->i_intra_cost = frame->lowres_costs[0][0];
             memset( frame->i_intra_cost, -1, (i_mb_count+3) * sizeof(uint16_t) );
         }
@@ -199,19 +195,17 @@ void x264_frame_delete( x264_frame_t *frame )
         x264_free( frame->i_propagate_cost );
         for( int j = 0; j <= X264_BFRAME_MAX+1; j++ )
             for( int i = 0; i <= X264_BFRAME_MAX+1; i++ )
-            {
                 x264_free( frame->lowres_costs[j][i] );
-                x264_free( frame->lowres_inter_types[j][i] );
-            }
         x264_free( frame->f_qp_offset );
         x264_free( frame->f_qp_offset_aq );
         x264_free( frame->i_inv_qscale_factor );
         x264_free( frame->i_row_bits );
-        x264_free( frame->i_row_qp );
+        x264_free( frame->f_row_qp );
         x264_free( frame->mb_type );
         x264_free( frame->mb_partition );
         x264_free( frame->mv[0] );
         x264_free( frame->mv[1] );
+        x264_free( frame->mv16x16 );
         x264_free( frame->ref[0] );
         x264_free( frame->ref[1] );
         x264_pthread_mutex_destroy( &frame->mutex );
@@ -225,7 +219,7 @@ int x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
     int i_csp = src->img.i_csp & X264_CSP_MASK;
     if( i_csp != X264_CSP_I420 && i_csp != X264_CSP_YV12 )
     {
-        x264_log( h, X264_LOG_ERROR, "Arg invalid CSP\n" );
+        x264_log( h, X264_LOG_ERROR, "Invalid input colorspace\n" );
         return -1;
     }
 
@@ -247,31 +241,40 @@ int x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
             plane += (height-1)*stride;
             stride = -stride;
         }
+        if( width > abs(stride) )
+        {
+            x264_log( h, X264_LOG_ERROR, "Input picture width is greater than stride\n" );
+            return -1;
+        }
         h->mc.plane_copy( dst->plane[i], dst->i_stride[i], plane, stride, width, height );
     }
     return 0;
 }
 
+static void ALWAYS_INLINE pixel_memset( pixel *dst, int value, int size )
+{
+    for( int i = 0; i < size; i++ )
+        dst[i] = value;
+}
 
-
-static void plane_expand_border( uint8_t *pix, int i_stride, int i_width, int i_height, int i_padh, int i_padv, int b_pad_top, int b_pad_bottom )
+static void plane_expand_border( pixel *pix, int i_stride, int i_width, int i_height, int i_padh, int i_padv, int b_pad_top, int b_pad_bottom )
 {
 #define PPIXEL(x, y) ( pix + (x) + (y)*i_stride )
     for( int y = 0; y < i_height; y++ )
     {
         /* left band */
-        memset( PPIXEL(-i_padh, y), PPIXEL(0, y)[0], i_padh );
+        pixel_memset( PPIXEL(-i_padh, y), PPIXEL(0, y)[0], i_padh );
         /* right band */
-        memset( PPIXEL(i_width, y), PPIXEL(i_width-1, y)[0], i_padh );
+        pixel_memset( PPIXEL(i_width, y), PPIXEL(i_width-1, y)[0], i_padh );
     }
     /* upper band */
     if( b_pad_top )
         for( int y = 0; y < i_padv; y++ )
-            memcpy( PPIXEL(-i_padh, -y-1), PPIXEL(-i_padh, 0), i_width+2*i_padh );
+            memcpy( PPIXEL(-i_padh, -y-1), PPIXEL(-i_padh, 0), (i_width+2*i_padh) * sizeof(pixel) );
     /* lower band */
     if( b_pad_bottom )
         for( int y = 0; y < i_padv; y++ )
-            memcpy( PPIXEL(-i_padh, i_height+y), PPIXEL(-i_padh, i_height-1), i_width+2*i_padh );
+            memcpy( PPIXEL(-i_padh, i_height+y), PPIXEL(-i_padh, i_height-1), (i_width+2*i_padh) * sizeof(pixel) );
 #undef PPIXEL
 }
 
@@ -288,7 +291,7 @@ void x264_frame_expand_border( x264_t *h, x264_frame_t *frame, int mb_y, int b_e
         int padh = PADH >> !!i;
         int padv = PADV >> !!i;
         // buffer: 2 chroma, 3 luma (rounded to 4) because deblocking goes beyond the top of the mb
-        uint8_t *pix = frame->plane[i] + X264_MAX(0, (16*mb_y-4)*stride >> !!i);
+        pixel *pix = frame->plane[i] + X264_MAX(0, (16*mb_y-4)*stride >> !!i);
         if( b_end && !b_start )
             height += 4 >> (!!i + h->sh.b_mbaff);
         if( h->sh.b_mbaff )
@@ -317,7 +320,7 @@ void x264_frame_expand_border_filtered( x264_t *h, x264_frame_t *frame, int mb_y
     for( int i = 1; i < 4; i++ )
     {
         // buffer: 8 luma, to match the hpel filter
-        uint8_t *pix = frame->filtered[i] + (16*mb_y - (8 << h->sh.b_mbaff)) * stride - 4;
+        pixel *pix = frame->filtered[i] + (16*mb_y - (8 << h->sh.b_mbaff)) * stride - 4;
         if( h->sh.b_mbaff )
         {
             plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end );
@@ -347,16 +350,17 @@ void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame )
         if( i_padx )
         {
             for( int y = 0; y < i_height; y++ )
-                memset( &frame->plane[i][y*frame->i_stride[i] + i_width],
-                         frame->plane[i][y*frame->i_stride[i] + i_width - 1],
-                         i_padx );
+            {
+                pixel value = frame->plane[i][y*frame->i_stride[i] + i_width - 1];
+                pixel_memset( &frame->plane[i][y*frame->i_stride[i] + i_width], value, i_padx );
+            }
         }
         if( i_pady )
         {
             for( int y = i_height; y < i_height + i_pady; y++ )
                 memcpy( &frame->plane[i][y*frame->i_stride[i]],
                         &frame->plane[i][(i_height-(~y&h->param.b_interlaced)-1)*frame->i_stride[i]],
-                        i_width + i_padx );
+                        (i_width + i_padx) * sizeof(pixel) );
         }
     }
 }
@@ -488,7 +492,7 @@ void x264_frame_sort( x264_frame_t **list, int b_dts )
     } while( !b_ok );
 }
 
-void x264_weight_scale_plane( x264_t *h, uint8_t *dst, int i_dst_stride, uint8_t *src, int i_src_stride,
+void x264_weight_scale_plane( x264_t *h, pixel *dst, int i_dst_stride, pixel *src, int i_src_stride,
                          int i_width, int i_height, x264_weight_t *w )
 {
     /* Weight horizontal strips of height 16. This was found to be the optimal height