3 Copyright (c) 2003-2015 HandBrake Team
4 This file is part of the HandBrake source code
5 Homepage: <http://handbrake.fr/>.
6 It may be used under the terms of the GNU General Public License v2.
7 For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
15 struct hb_filter_private_s
30 hb_oclscale_t
*os
; //ocl scaler handler
32 struct SwsContext
* context
;
35 static int hb_crop_scale_init( hb_filter_object_t
* filter
,
36 hb_filter_init_t
* init
);
38 static int hb_crop_scale_work( hb_filter_object_t
* filter
,
39 hb_buffer_t
** buf_in
,
40 hb_buffer_t
** buf_out
);
42 static int hb_crop_scale_info( hb_filter_object_t
* filter
,
43 hb_filter_info_t
* info
);
45 static void hb_crop_scale_close( hb_filter_object_t
* filter
);
47 hb_filter_object_t hb_filter_crop_scale
=
49 .id
= HB_FILTER_CROP_SCALE
,
51 .name
= "Crop and Scale",
53 .init
= hb_crop_scale_init
,
54 .work
= hb_crop_scale_work
,
55 .close
= hb_crop_scale_close
,
56 .info
= hb_crop_scale_info
,
59 static int hb_crop_scale_init( hb_filter_object_t
* filter
,
60 hb_filter_init_t
* init
)
62 filter
->private_data
= calloc( 1, sizeof(struct hb_filter_private_s
) );
63 hb_filter_private_t
* pv
= filter
->private_data
;
65 // TODO: add pix format option to settings
67 pv
->pix_fmt_out
= init
->pix_fmt
;
68 pv
->width_in
= init
->geometry
.width
;
69 pv
->height_in
= init
->geometry
.height
;
70 pv
->width_out
= init
->geometry
.width
- (init
->crop
[2] + init
->crop
[3]);
71 pv
->height_out
= init
->geometry
.height
- (init
->crop
[0] + init
->crop
[1]);
74 pv
->use_dxva
= hb_hwd_enabled(init
->job
->h
);
75 pv
->use_decomb
= init
->job
->use_decomb
;
76 pv
->use_detelecine
= init
->job
->use_detelecine
;
78 if (pv
->job
->use_opencl
&& pv
->job
->title
->opencl_support
)
80 pv
->os
= ( hb_oclscale_t
* )malloc( sizeof( hb_oclscale_t
) );
81 memset( pv
->os
, 0, sizeof( hb_oclscale_t
) );
84 memcpy( pv
->crop
, init
->crop
, sizeof( int[4] ) );
85 if( filter
->settings
)
87 sscanf( filter
->settings
, "%d:%d:%d:%d:%d:%d",
88 &pv
->width_out
, &pv
->height_out
,
89 &pv
->crop
[0], &pv
->crop
[1], &pv
->crop
[2], &pv
->crop
[3] );
91 // Set init values so the next stage in the pipline
92 // knows what it will be getting
93 init
->pix_fmt
= pv
->pix_fmt
;
94 init
->geometry
.width
= pv
->width_out
;
95 init
->geometry
.height
= pv
->height_out
;
96 memcpy( init
->crop
, pv
->crop
, sizeof( int[4] ) );
101 static int hb_crop_scale_info( hb_filter_object_t
* filter
,
102 hb_filter_info_t
* info
)
104 hb_filter_private_t
* pv
= filter
->private_data
;
109 // Set init values so the next stage in the pipline
110 // knows what it will be getting
111 memset( info
, 0, sizeof( hb_filter_info_t
) );
112 info
->out
.pix_fmt
= pv
->pix_fmt
;
113 info
->out
.geometry
.width
= pv
->width_out
;
114 info
->out
.geometry
.height
= pv
->height_out
;
115 memcpy( info
->out
.crop
, pv
->crop
, sizeof( int[4] ) );
117 int cropped_width
= pv
->width_in
- ( pv
->crop
[2] + pv
->crop
[3] );
118 int cropped_height
= pv
->height_in
- ( pv
->crop
[0] + pv
->crop
[1] );
120 sprintf( info
->human_readable_desc
,
121 "source: %d * %d, crop (%d/%d/%d/%d): %d * %d, scale: %d * %d",
122 pv
->width_in
, pv
->height_in
,
123 pv
->crop
[0], pv
->crop
[1], pv
->crop
[2], pv
->crop
[3],
124 cropped_width
, cropped_height
, pv
->width_out
, pv
->height_out
);
129 static void hb_crop_scale_close( hb_filter_object_t
* filter
)
131 hb_filter_private_t
* pv
= filter
->private_data
;
139 if (pv
->job
->use_opencl
&& pv
->job
->title
->opencl_support
&& pv
->os
)
143 HB_OCL_BUF_FREE(hb_ocl
, pv
->os
->bicubic_x_weights
);
144 HB_OCL_BUF_FREE(hb_ocl
, pv
->os
->bicubic_y_weights
);
151 sws_freeContext( pv
->context
);
155 filter
->private_data
= NULL
;
159 static hb_buffer_t
* crop_scale( hb_filter_private_t
* pv
, hb_buffer_t
* in
)
165 out
= hb_video_buffer_init( pv
->width_out
, pv
->height_out
);
167 hb_avpicture_fill( &pic_in
, in
);
168 hb_avpicture_fill( &pic_out
, out
);
170 // Crop; this alters the pointer to the data to point to the
171 // correct place for cropped frame
172 av_picture_crop( &pic_crop
, &pic_in
, in
->f
.fmt
,
173 pv
->crop
[0], pv
->crop
[2] );
175 // Use bicubic OpenCL scaling when selected and when downsampling < 4:1;
176 if ((pv
->job
->use_opencl
&& pv
->job
->title
->opencl_support
) &&
177 (pv
->width_out
* 4 > pv
->width_in
) &&
178 (in
->cl
.buffer
!= NULL
) && (out
->cl
.buffer
!= NULL
))
181 hb_ocl_scale(in
, out
, pv
->crop
, pv
->os
);
185 if (pv
->context
== NULL
||
186 pv
->width_in
!= in
->f
.width
||
187 pv
->height_in
!= in
->f
.height
||
188 pv
->pix_fmt
!= in
->f
.fmt
)
190 // Something changed, need a new scaling context.
191 if (pv
->context
!= NULL
)
193 sws_freeContext(pv
->context
);
196 pv
->context
= hb_sws_get_context(in
->f
.width
- (pv
->crop
[2] + pv
->crop
[3]),
197 in
->f
.height
- (pv
->crop
[0] + pv
->crop
[1]),
198 in
->f
.fmt
, out
->f
.width
, out
->f
.height
,
199 out
->f
.fmt
, SWS_LANCZOS
|SWS_ACCURATE_RND
);
200 pv
->width_in
= in
->f
.width
;
201 pv
->height_in
= in
->f
.height
;
202 pv
->pix_fmt
= in
->f
.fmt
;
205 if (pv
->context
== NULL
)
207 hb_buffer_close(&out
);
211 // Scale pic_crop into pic_render according to the
212 // context set up above
213 sws_scale(pv
->context
,
214 (const uint8_t* const*)pic_crop
.data
, pic_crop
.linesize
,
215 0, in
->f
.height
- (pv
->crop
[0] + pv
->crop
[1]),
216 pic_out
.data
, pic_out
.linesize
);
220 hb_buffer_move_subs( out
, in
);
224 static int hb_crop_scale_work( hb_filter_object_t
* filter
,
225 hb_buffer_t
** buf_in
,
226 hb_buffer_t
** buf_out
)
228 hb_filter_private_t
* pv
= filter
->private_data
;
229 hb_buffer_t
* in
= *buf_in
;
231 if (in
->s
.flags
& HB_BUF_FLAG_EOF
)
235 return HB_FILTER_DONE
;
245 // If width or height were not set, set them now based on the
246 // input width & height
247 if ( pv
->width_out
<= 0 || pv
->height_out
<= 0 )
249 pv
->width_out
= in
->f
.width
- (pv
->crop
[2] + pv
->crop
[3]);
250 pv
->height_out
= in
->f
.height
- (pv
->crop
[0] + pv
->crop
[1]);
254 if ((!pv
->use_dxva
&&
255 !pv
->crop
[0] && !pv
->crop
[1] && !pv
->crop
[2] && !pv
->crop
[3] &&
256 in
->f
.fmt
== pv
->pix_fmt_out
&& in
->f
.width
== pv
->width_out
&&
257 in
->f
.height
== pv
->height_out
) ||
258 (pv
->use_dxva
&& !pv
->use_decomb
&& !pv
->use_detelecine
&&
259 in
->f
.width
== pv
->width_out
&& in
->f
.height
== pv
->height_out
))
266 *buf_out
= crop_scale(pv
, in
);