summaryrefslogtreecommitdiffstats
path: root/libhb/cropscale.c
diff options
context:
space:
mode:
Diffstat (limited to 'libhb/cropscale.c')
-rw-r--r--libhb/cropscale.c81
1 files changed, 79 insertions, 2 deletions
diff --git a/libhb/cropscale.c b/libhb/cropscale.c
index d217393d1..c7d7d9948 100644
--- a/libhb/cropscale.c
+++ b/libhb/cropscale.c
@@ -9,9 +9,12 @@
#include "hb.h"
#include "hbffmpeg.h"
+#include "common.h"
+
struct hb_filter_private_s
{
+ hb_job_t *job;
int width_in;
int height_in;
int pix_fmt;
@@ -19,6 +22,13 @@ struct hb_filter_private_s
int width_out;
int height_out;
int crop[4];
+
+#ifdef USE_OPENCL
+ int use_dxva;
+ int use_decomb;
+ int use_detelecine;
+ hb_oclscale_t *os; //ocl scaler handler
+#endif
struct SwsContext * context;
};
@@ -53,11 +63,23 @@ static int hb_crop_scale_init( hb_filter_object_t * filter,
hb_filter_private_t * pv = filter->private_data;
// TODO: add pix format option to settings
+ pv->job = init->job;
pv->pix_fmt_out = init->pix_fmt;
pv->width_in = init->width;
pv->height_in = init->height;
pv->width_out = init->width - (init->crop[2] + init->crop[3]);
pv->height_out = init->height - (init->crop[0] + init->crop[1]);
+#ifdef USE_OPENCL
+ pv->use_dxva = init->use_dxva;
+ pv->use_decomb = init->job->use_decomb;
+ pv->use_detelecine = init->job->use_detelecine;
+
+ if( pv->job->use_opencl )
+ {
+ pv->os = ( hb_oclscale_t * )malloc( sizeof( hb_oclscale_t ) );
+ memset( pv->os, 0, sizeof( hb_oclscale_t ) );
+ }
+#endif
memcpy( pv->crop, init->crop, sizeof( int[4] ) );
if( filter->settings )
{
@@ -71,6 +93,9 @@ static int hb_crop_scale_init( hb_filter_object_t * filter,
init->width = pv->width_out;
init->height = pv->height_out;
memcpy( init->crop, pv->crop, sizeof( int[4] ) );
+#ifdef USE_OPENCL
+ pv->use_dxva = init->use_dxva;
+#endif
return 0;
}
@@ -111,8 +136,16 @@ static void hb_crop_scale_close( hb_filter_object_t * filter )
{
return;
}
+#ifdef USE_OPENCL
- if ( pv->context )
+ if( pv->job->use_opencl && pv->os )
+ {
+ CL_FREE( pv->os->bicubic_x_weights );
+ CL_FREE( pv->os->bicubic_y_weights );
+ free( pv->os );
+ }
+#endif
+ if( pv->context )
{
sws_freeContext( pv->context );
}
@@ -121,6 +154,25 @@ static void hb_crop_scale_close( hb_filter_object_t * filter )
filter->private_data = NULL;
}
+#ifdef USE_OPENCL
+static uint8_t *copy_plane( uint8_t *dst, uint8_t* src, int dstride, int sstride, int h )
+{
+ if( dstride == sstride )
+ {
+ memcpy( dst, src, dstride * h );
+ return dst + dstride * h;
+ }
+ int lbytes = dstride <= sstride ? dstride : sstride;
+ while( --h >= 0 )
+ {
+ memcpy( dst, src, lbytes );
+ src += sstride;
+ dst += dstride;
+ }
+ return dst;
+}
+#endif
+
static hb_buffer_t* crop_scale( hb_filter_private_t * pv, hb_buffer_t * in )
{
AVPicture pic_in;
@@ -137,6 +189,15 @@ static hb_buffer_t* crop_scale( hb_filter_private_t * pv, hb_buffer_t * in )
av_picture_crop( &pic_crop, &pic_in, in->f.fmt,
pv->crop[0], pv->crop[2] );
+#ifdef USE_OPENCL
+ // Use bicubic OpenCL scaling when selected and when downsampling < 4:1;
+ if ((pv->job->use_opencl) && (pv->width_out * 4 > pv->width_in) && (in->cl.buffer != NULL) && (out->cl.buffer != NULL))
+ {
+ hb_ocl_scale(in, out, pv->crop, pv->os);
+ }
+ else
+ {
+#endif
if ( !pv->context ||
pv->width_in != in->f.width ||
pv->height_in != in->f.height ||
@@ -164,7 +225,9 @@ static hb_buffer_t* crop_scale( hb_filter_private_t * pv, hb_buffer_t * in )
pic_crop.linesize,
0, in->f.height - (pv->crop[0] + pv->crop[1]),
pic_out.data, pic_out.linesize);
-
+#ifdef USE_OPENCL
+ }
+#endif
out->s = in->s;
hb_buffer_move_subs( out, in );
return out;
@@ -198,6 +261,18 @@ static int hb_crop_scale_work( hb_filter_object_t * filter,
pv->width_out = in->f.width - (pv->crop[2] + pv->crop[3]);
pv->height_out = in->f.height - (pv->crop[0] + pv->crop[1]);
}
+#ifdef USE_OPENCL
+ if ( (in->f.fmt == pv->pix_fmt_out &&
+ !pv->crop[0] && !pv->crop[1] && !pv->crop[2] && !pv->crop[3] &&
+ in->f.width == pv->width_out && in->f.height == pv->height_out) &&
+ (pv->use_decomb == 0) && (pv->use_detelecine == 0) ||
+ (pv->use_dxva && in->f.width == pv->width_out && in->f.height == pv->height_out) )
+ {
+ *buf_out = in;
+ *buf_in = NULL;
+ return HB_FILTER_OK;
+ }
+#else
if ( in->f.fmt == pv->pix_fmt_out &&
!pv->crop[0] && !pv->crop[1] && !pv->crop[2] && !pv->crop[3] &&
in->f.width == pv->width_out && in->f.height == pv->height_out )
@@ -206,6 +281,8 @@ static int hb_crop_scale_work( hb_filter_object_t * filter,
*buf_in = NULL;
return HB_FILTER_OK;
}
+#endif
+
*buf_out = crop_scale( pv, in );
return HB_FILTER_OK;