summaryrefslogtreecommitdiffstats
path: root/libhb/rotate.c
diff options
context:
space:
mode:
Diffstat (limited to 'libhb/rotate.c')
-rw-r--r--libhb/rotate.c284
1 files changed, 153 insertions, 131 deletions
diff --git a/libhb/rotate.c b/libhb/rotate.c
index efa825a91..5f9558764 100644
--- a/libhb/rotate.c
+++ b/libhb/rotate.c
@@ -9,19 +9,18 @@
// Mode 3: Flip both horizontally and vertically (modes 1 and 2 combined)
typedef struct rotate_arguments_s {
- uint8_t **dst;
+ hb_buffer_t *dst;
+ hb_buffer_t *src;
int stop;
} rotate_arguments_t;
struct hb_filter_private_s
{
- int pix_fmt;
- int width[3];
- int height[3];
-
int mode;
-
- int ref_stride[3];
+ int width;
+ int height;
+ int par_width;
+ int par_height;
int cpu_count;
@@ -29,60 +28,33 @@ struct hb_filter_private_s
hb_lock_t ** rotate_begin_lock; // Thread has work
hb_lock_t ** rotate_complete_lock; // Thread has completed work
rotate_arguments_t *rotate_arguments; // Arguments to thread for work
-
- AVPicture pic_in;
- AVPicture pic_out;
- hb_buffer_t * buf_out;
- hb_buffer_t * buf_settings;
};
-hb_filter_private_t * hb_rotate_init( int pix_fmt,
- int width,
- int height,
- char * settings );
+static int hb_rotate_init( hb_filter_object_t * filter,
+ hb_filter_init_t * init );
-int hb_rotate_work( hb_buffer_t * buf_in,
- hb_buffer_t ** buf_out,
- int pix_fmt,
- int width,
- int height,
- hb_filter_private_t * pv );
+static int hb_rotate_work( hb_filter_object_t * filter,
+ hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out );
-void hb_rotate_close( hb_filter_private_t * pv );
+static void hb_rotate_close( hb_filter_object_t * filter );
+
+static int hb_rotate_info( hb_filter_object_t * filter,
+ hb_filter_info_t * info );
hb_filter_object_t hb_filter_rotate =
{
- FILTER_ROTATE,
- "Rotate (flips image axes)",
- NULL,
- hb_rotate_init,
- hb_rotate_work,
- hb_rotate_close,
+ .id = HB_FILTER_ROTATE,
+ .enforce_order = 0,
+ .name = "Rotate (rotate & flip image axes)",
+ .settings = NULL,
+ .init = hb_rotate_init,
+ .work = hb_rotate_work,
+ .close = hb_rotate_close,
+ .info = hb_rotate_info
};
-static void rotate_filter_line( uint8_t *dst,
- uint8_t *cur,
- int plane,
- hb_filter_private_t * pv )
-{
-
- int w = pv->width[plane];
-
- int x;
- for( x = 0; x < w; x++)
- {
- if( pv->mode & 2 )
- {
- dst[x] = cur[w-x-1];
- }
- else
- {
- dst[x] = cur[x];
- }
- }
-}
-
typedef struct rotate_thread_arg_s {
hb_filter_private_t *pv;
int segment;
@@ -99,8 +71,10 @@ void rotate_filter_thread( void *thread_args_v )
int plane;
int segment, segment_start, segment_stop;
rotate_thread_arg_t *thread_args = thread_args_v;
- uint8_t **dst;
- int y, w, h, ref_stride;
+ uint8_t *dst;
+ hb_buffer_t *dst_buf;
+ hb_buffer_t *src_buf;
+ int y;
pv = thread_args->pv;
@@ -137,13 +111,18 @@ void rotate_filter_thread( void *thread_args_v )
/*
* Process all three planes, but only this segment of it.
*/
+ dst_buf = rotate_work->dst;
+ src_buf = rotate_work->src;
for( plane = 0; plane < 3; plane++)
{
+ int dst_stride, src_stride;
+
+ dst = dst_buf->plane[plane].data;
+ dst_stride = dst_buf->plane[plane].stride;
+ src_stride = src_buf->plane[plane].stride;
- dst = rotate_work->dst;
- w = pv->width[plane];
- h = pv->height[plane];
- ref_stride = pv->ref_stride[plane];
+ int h = src_buf->plane[plane].height;
+ int w = src_buf->plane[plane].width;
segment_start = ( h / pv->cpu_count ) * segment;
if( segment == pv->cpu_count - 1 )
{
@@ -158,21 +137,35 @@ void rotate_filter_thread( void *thread_args_v )
for( y = segment_start; y < segment_stop; y++ )
{
uint8_t * cur;
-
- if( pv->mode & 1 )
- {
- cur = &pv->pic_in.data[plane][(h-y-1)*pv->pic_in.linesize[plane]];
- }
- else
+ int x, xo, yo;
+
+ cur = &src_buf->plane[plane].data[y * src_stride];
+ for( x = 0; x < w; x++)
{
- cur = &pv->pic_in.data[plane][(y)*pv->pic_in.linesize[plane]];
+ if( pv->mode & 1 )
+ {
+ yo = h - y - 1;
+ }
+ else
+ {
+ yo = y;
+ }
+ if( pv->mode & 2 )
+ {
+ xo = w - x - 1;
+ }
+ else
+ {
+ xo = x;
+ }
+ if( pv->mode & 4 ) // Rotate 90 clockwise
+ {
+ int tmp = xo;
+ xo = h - yo - 1;
+ yo = tmp;
+ }
+ dst[yo*dst_stride + xo] = cur[x];
}
- uint8_t *dst2 = &dst[plane][y*w];
-
- rotate_filter_line( dst2,
- cur,
- plane,
- pv );
}
}
/*
@@ -185,14 +178,16 @@ void rotate_filter_thread( void *thread_args_v )
/*
- * threaded rotate - each thread rptates a single segment of all
+ * threaded rotate - each thread rotates a single segment of all
* three planes. Where a segment is defined as the frame divided by
* the number of CPUs.
*
* This function blocks until the frame is rotated.
*/
-static void rotate_filter( uint8_t ** dst,
- hb_filter_private_t * pv )
+static void rotate_filter(
+ hb_filter_private_t * pv,
+ hb_buffer_t *out,
+ hb_buffer_t *in )
{
int segment;
@@ -202,7 +197,8 @@ static void rotate_filter( uint8_t ** dst,
/*
* Setup the work for this plane.
*/
- pv->rotate_arguments[segment].dst = dst;
+ pv->rotate_arguments[segment].dst = out;
+ pv->rotate_arguments[segment].src = in;
/*
* Let the thread for this plane know that we've setup work
@@ -232,37 +228,17 @@ static void rotate_filter( uint8_t ** dst,
}
-hb_filter_private_t * hb_rotate_init( int pix_fmt,
- int width,
- int height,
- char * settings )
+static int hb_rotate_init( hb_filter_object_t * filter,
+ hb_filter_init_t * init )
{
- if( pix_fmt != PIX_FMT_YUV420P )
- {
- return 0;
- }
-
- hb_filter_private_t * pv = calloc( 1, sizeof(struct hb_filter_private_s) );
-
- pv->pix_fmt = pix_fmt;
-
- pv->width[0] = width;
- pv->height[0] = height;
- pv->width[1] = pv->width[2] = width >> 1;
- pv->height[1] = pv->height[2] = height >> 1;
-
- pv->buf_out = hb_video_buffer_init( width, height );
- pv->buf_settings = hb_buffer_init( 0 );
+ filter->private_data = calloc( 1, sizeof(struct hb_filter_private_s) );
+ hb_filter_private_t * pv = filter->private_data;
pv->mode = MODE_DEFAULT;
- pv->ref_stride[0] = pv->width[0];
- pv->ref_stride[1] = pv->width[1];
- pv->ref_stride[2] = pv->width[2];
-
- if( settings )
+ if( filter->settings )
{
- sscanf( settings, "%d",
+ sscanf( filter->settings, "%d",
&pv->mode );
}
@@ -308,25 +284,64 @@ hb_filter_private_t * hb_rotate_init( int pix_fmt,
hb_error( "rotate could not create threads" );
}
}
+ // Set init width/height so the next stage in the pipline
+ // knows what it will be getting
+ if( pv->mode & 4 )
+ {
+ // 90 degree rotation, exchange width and height
+ int tmp = init->width;
+ init->width = init->height;
+ init->height = tmp;
+
+ tmp = init->par_width;
+ init->par_width = init->par_height;
+ init->par_height = tmp;
+ }
+ pv->width = init->width;
+ pv->height = init->height;
+ pv->par_width = init->par_width;
+ pv->par_height = init->par_height;
- return pv;
+ return 0;
}
-void hb_rotate_close( hb_filter_private_t * pv )
+static int hb_rotate_info( hb_filter_object_t * filter,
+ hb_filter_info_t * info )
{
+ hb_filter_private_t * pv = filter->private_data;
if( !pv )
+ return 1;
+
+ memset( info, 0, sizeof( hb_filter_info_t ) );
+ info->out.width = pv->width;
+ info->out.height = pv->height;
+ info->out.par_width = pv->par_width;
+ info->out.par_height = pv->par_height;
+ int pos = 0;
+ if( pv->mode & 1 )
+ pos += sprintf( &info->human_readable_desc[pos], "flip vertical" );
+ if( pv->mode & 2 )
{
- return;
+ if( pos )
+ pos += sprintf( &info->human_readable_desc[pos], "/" );
+ pos += sprintf( &info->human_readable_desc[pos], "flip horizontal" );
}
-
- /* Cleanup frame buffers */
- if( pv->buf_out )
+ if( pv->mode & 4 )
{
- hb_buffer_close( &pv->buf_out );
+ if( pos )
+ pos += sprintf( &info->human_readable_desc[pos], "/" );
+ pos += sprintf( &info->human_readable_desc[pos], "rotate 90" );
}
- if (pv->buf_settings )
+ return 0;
+}
+
+static void hb_rotate_close( hb_filter_object_t * filter )
+{
+ hb_filter_private_t * pv = filter->private_data;
+
+ if( !pv )
{
- hb_buffer_close( &pv->buf_settings );
+ return;
}
int i;
@@ -352,36 +367,43 @@ void hb_rotate_close( hb_filter_private_t * pv )
free( pv->rotate_arguments );
free( pv );
+ filter->private_data = NULL;
}
-int hb_rotate_work( hb_buffer_t * buf_in,
- hb_buffer_t ** buf_out,
- int pix_fmt,
- int width,
- int height,
- hb_filter_private_t * pv )
+static int hb_rotate_work( hb_filter_object_t * filter,
+ hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out )
{
- if( !pv ||
- pix_fmt != pv->pix_fmt ||
- width != pv->width[0] ||
- height != pv->height[0] )
+ hb_filter_private_t * pv = filter->private_data;
+ hb_buffer_t * in = *buf_in, * out;
+
+ if ( in->size <= 0 )
{
- return FILTER_FAILED;
+ *buf_out = in;
+ *buf_in = NULL;
+ return HB_FILTER_DONE;
}
- avpicture_fill( &pv->pic_in, buf_in->data,
- pix_fmt, width, height );
+ int width_out, height_out;
+ if ( pv->mode & 4 )
+ {
+ width_out = in->f.height;
+ height_out = in->f.width;
+ }
+ else
+ {
+ width_out = in->f.width;
+ height_out = in->f.height;
+ }
- avpicture_fill( &pv->pic_out, pv->buf_out->data,
- pix_fmt, width, height );
+ out = hb_video_buffer_init( width_out, height_out );
- //do stuff here
- rotate_filter( pv->pic_out.data, pv );
- hb_buffer_copy_settings( pv->buf_out, buf_in );
+ // Rotate!
+ rotate_filter( pv, out, in );
+ out->s = in->s;
+ hb_buffer_move_subs( out, in );
- *buf_out = pv->buf_out;
+ *buf_out = out;
- return FILTER_OK;
+ return HB_FILTER_OK;
}
-
-