comparison libmpcodecs/vf_scale.c @ 11700:272fc35fd8ee

interlaced scaling
author michael
date Mon, 29 Dec 2003 14:16:07 +0000
parents 93a76eee7657
children 21e5cb258a95
comparison
equal deleted inserted replaced
11699:9165fbc7d89d 11700:272fc35fd8ee
22 int w,h; 22 int w,h;
23 int v_chr_drop; 23 int v_chr_drop;
24 int param; 24 int param;
25 unsigned int fmt; 25 unsigned int fmt;
26 struct SwsContext *ctx; 26 struct SwsContext *ctx;
27 struct SwsContext *ctx2; //for interlaced slices only
27 unsigned char* palette; 28 unsigned char* palette;
29 int interlaced;
28 int query_format_cache[64]; 30 int query_format_cache[64];
29 } vf_priv_dflt = { 31 } vf_priv_dflt = {
30 -1,-1, 32 -1,-1,
31 0, 33 0,
32 0, 34 0,
33 0, 35 0,
36 NULL,
34 NULL, 37 NULL,
35 NULL 38 NULL
36 }; 39 };
37 40
38 extern int opt_screen_size_x; 41 extern int opt_screen_size_x;
175 width,height,vo_format_name(outfmt), 178 width,height,vo_format_name(outfmt),
176 vf->priv->w,vf->priv->h,vo_format_name(best)); 179 vf->priv->w,vf->priv->h,vo_format_name(best));
177 180
178 // free old ctx: 181 // free old ctx:
179 if(vf->priv->ctx) sws_freeContext(vf->priv->ctx); 182 if(vf->priv->ctx) sws_freeContext(vf->priv->ctx);
183 if(vf->priv->ctx2)sws_freeContext(vf->priv->ctx2);
180 184
181 // new swscaler: 185 // new swscaler:
182 sws_getFlagsAndFilterFromCmdLine(&int_sws_flags, &srcFilter, &dstFilter); 186 sws_getFlagsAndFilterFromCmdLine(&int_sws_flags, &srcFilter, &dstFilter);
183 int_sws_flags|= vf->priv->v_chr_drop << SWS_SRC_V_CHR_DROP_SHIFT; 187 int_sws_flags|= vf->priv->v_chr_drop << SWS_SRC_V_CHR_DROP_SHIFT;
184 int_sws_flags|= vf->priv->param << SWS_PARAM_SHIFT; 188 int_sws_flags|= vf->priv->param << SWS_PARAM_SHIFT;
185 vf->priv->ctx=sws_getContext(width,height, 189 vf->priv->ctx=sws_getContext(width, height >> vf->priv->interlaced,
186 outfmt, 190 outfmt,
187 vf->priv->w,vf->priv->h, 191 vf->priv->w, vf->priv->h >> vf->priv->interlaced,
188 best, 192 best,
189 int_sws_flags | get_sws_cpuflags(), srcFilter, dstFilter); 193 int_sws_flags | get_sws_cpuflags(), srcFilter, dstFilter);
194 if(vf->priv->interlaced){
195 vf->priv->ctx2=sws_getContext(width, height >> 1,
196 outfmt,
197 vf->priv->w, vf->priv->h >> 1,
198 best,
199 int_sws_flags | get_sws_cpuflags(), srcFilter, dstFilter);
200 }
190 if(!vf->priv->ctx){ 201 if(!vf->priv->ctx){
191 // error... 202 // error...
192 mp_msg(MSGT_VFILTER,MSGL_WARN,"Couldn't init SwScaler for this setup\n"); 203 mp_msg(MSGT_VFILTER,MSGL_WARN,"Couldn't init SwScaler for this setup\n");
193 return 0; 204 return 0;
194 } 205 }
245 // mpi->type, mpi->flags & (~MP_IMGFLAG_DRAW_CALLBACK), 256 // mpi->type, mpi->flags & (~MP_IMGFLAG_DRAW_CALLBACK),
246 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE, 257 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
247 vf->priv->w, vf->priv->h); 258 vf->priv->w, vf->priv->h);
248 } 259 }
249 260
261 static void scale(struct SwsContext *sws1, struct SwsContext *sws2, uint8_t *src[3], int src_stride[3], int y, int h,
262 uint8_t *dst[3], int dst_stride[3], int interlaced){
263 if(interlaced){
264 int i;
265 uint8_t *src2[3]={src[0], src[1], src[2]};
266 uint8_t *dst2[3]={dst[0], dst[1], dst[2]};
267 int src_stride2[3]={2*src_stride[0], 2*src_stride[1], 2*src_stride[2]};
268 int dst_stride2[3]={2*dst_stride[0], 2*dst_stride[1], 2*dst_stride[2]};
269
270 sws_scale_ordered(sws1, src2, src_stride2, y>>1, h>>1, dst2, dst_stride2);
271 for(i=0; i<3; i++){
272 src2[i] += src_stride[i];
273 dst2[i] += dst_stride[i];
274 }
275 sws_scale_ordered(sws2, src2, src_stride2, y>>1, h>>1, dst2, dst_stride2);
276 }else{
277 sws_scale_ordered(sws1, src, src_stride, y, h, dst, dst_stride);
278 }
279 }
280
250 static void draw_slice(struct vf_instance_s* vf, 281 static void draw_slice(struct vf_instance_s* vf,
251 unsigned char** src, int* stride, int w,int h, int x, int y){ 282 unsigned char** src, int* stride, int w,int h, int x, int y){
252 mp_image_t *dmpi=vf->dmpi; 283 mp_image_t *dmpi=vf->dmpi;
253 if(!dmpi){ 284 if(!dmpi){
254 mp_msg(MSGT_VFILTER,MSGL_FATAL,"vf_scale: draw_slice() called with dmpi=NULL (no get_image??)\n"); 285 mp_msg(MSGT_VFILTER,MSGL_FATAL,"vf_scale: draw_slice() called with dmpi=NULL (no get_image??)\n");
255 return; 286 return;
256 } 287 }
257 // printf("vf_scale::draw_slice() y=%d h=%d\n",y,h); 288 // printf("vf_scale::draw_slice() y=%d h=%d\n",y,h);
258 sws_scale_ordered(vf->priv->ctx,src,stride,y,h,dmpi->planes,dmpi->stride); 289 scale(vf->priv->ctx, vf->priv->ctx2, src, stride, y, h, dmpi->planes, dmpi->stride, vf->priv->interlaced);
259 } 290 }
260 291
261 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){ 292 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
262 mp_image_t *dmpi=mpi->priv; 293 mp_image_t *dmpi=mpi->priv;
263 294
268 299
269 // hope we'll get DR buffer: 300 // hope we'll get DR buffer:
270 dmpi=vf_get_image(vf->next,vf->priv->fmt, 301 dmpi=vf_get_image(vf->next,vf->priv->fmt,
271 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE, 302 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
272 vf->priv->w, vf->priv->h); 303 vf->priv->w, vf->priv->h);
273 sws_scale_ordered(vf->priv->ctx,mpi->planes,mpi->stride,0,mpi->h,dmpi->planes,dmpi->stride); 304
274 305 scale(vf->priv->ctx, vf->priv->ctx, mpi->planes,mpi->stride,0,mpi->h,dmpi->planes,dmpi->stride, vf->priv->interlaced);
275 } 306 }
276 307
277 if(vf->priv->w==mpi->w && vf->priv->h==mpi->h){ 308 if(vf->priv->w==mpi->w && vf->priv->h==mpi->h){
278 // just conversion, no scaling -> keep postprocessing data 309 // just conversion, no scaling -> keep postprocessing data
279 // this way we can apply pp filter to non-yv12 source using scaler 310 // this way we can apply pp filter to non-yv12 source using scaler
329 else 360 else
330 break; 361 break;
331 362
332 r= sws_setColorspaceDetails(vf->priv->ctx, inv_table, srcRange, table, dstRange, brightness, contrast, saturation); 363 r= sws_setColorspaceDetails(vf->priv->ctx, inv_table, srcRange, table, dstRange, brightness, contrast, saturation);
333 if(r<0) break; 364 if(r<0) break;
365 if(vf->priv->ctx2){
366 r= sws_setColorspaceDetails(vf->priv->ctx2, inv_table, srcRange, table, dstRange, brightness, contrast, saturation);
367 if(r<0) break;
368 }
334 369
335 return CONTROL_TRUE; 370 return CONTROL_TRUE;
336 default: 371 default:
337 break; 372 break;
338 } 373 }
379 return 0; // nomatching in-fmt 414 return 0; // nomatching in-fmt
380 } 415 }
381 416
382 static void uninit(struct vf_instance_s *vf){ 417 static void uninit(struct vf_instance_s *vf){
383 if(vf->priv->ctx) sws_freeContext(vf->priv->ctx); 418 if(vf->priv->ctx) sws_freeContext(vf->priv->ctx);
419 if(vf->priv->ctx2) sws_freeContext(vf->priv->ctx2);
384 if(vf->priv->palette) free(vf->priv->palette); 420 if(vf->priv->palette) free(vf->priv->palette);
385 free(vf->priv); 421 free(vf->priv);
386 } 422 }
387 423
388 static int open(vf_instance_t *vf, char* args){ 424 static int open(vf_instance_t *vf, char* args){
395 vf->uninit=uninit; 431 vf->uninit=uninit;
396 if(!vf->priv) { 432 if(!vf->priv) {
397 vf->priv=malloc(sizeof(struct vf_priv_s)); 433 vf->priv=malloc(sizeof(struct vf_priv_s));
398 // TODO: parse args -> 434 // TODO: parse args ->
399 vf->priv->ctx=NULL; 435 vf->priv->ctx=NULL;
436 vf->priv->ctx2=NULL;
400 vf->priv->w= 437 vf->priv->w=
401 vf->priv->h=-1; 438 vf->priv->h=-1;
402 vf->priv->v_chr_drop=0; 439 vf->priv->v_chr_drop=0;
403 vf->priv->param=0; 440 vf->priv->param=0;
404 vf->priv->palette=NULL; 441 vf->priv->palette=NULL;
409 &vf->priv->v_chr_drop, 446 &vf->priv->v_chr_drop,
410 &vf->priv->param); 447 &vf->priv->param);
411 mp_msg(MSGT_VFILTER,MSGL_V,"SwScale params: %d x %d (-1=no scaling)\n", 448 mp_msg(MSGT_VFILTER,MSGL_V,"SwScale params: %d x %d (-1=no scaling)\n",
412 vf->priv->w, 449 vf->priv->w,
413 vf->priv->h); 450 vf->priv->h);
451
414 return 1; 452 return 1;
415 } 453 }
416 454
417 //global sws_flags from the command line 455 //global sws_flags from the command line
418 int sws_flags=2; 456 int sws_flags=2;
528 #undef ST_OFF 566 #undef ST_OFF
529 #define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f) 567 #define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f)
530 static m_option_t vf_opts_fields[] = { 568 static m_option_t vf_opts_fields[] = {
531 {"w", ST_OFF(w), CONF_TYPE_INT, M_OPT_MIN,-3 ,0, NULL}, 569 {"w", ST_OFF(w), CONF_TYPE_INT, M_OPT_MIN,-3 ,0, NULL},
532 {"h", ST_OFF(h), CONF_TYPE_INT, M_OPT_MIN,-3 ,0, NULL}, 570 {"h", ST_OFF(h), CONF_TYPE_INT, M_OPT_MIN,-3 ,0, NULL},
571 {"interlaced", ST_OFF(interlaced), CONF_TYPE_INT, M_OPT_RANGE, 0, 1, NULL},
533 {"chr-drop", ST_OFF(v_chr_drop), CONF_TYPE_INT, M_OPT_RANGE, 0, 3, NULL}, 572 {"chr-drop", ST_OFF(v_chr_drop), CONF_TYPE_INT, M_OPT_RANGE, 0, 3, NULL},
534 {"param", ST_OFF(param), CONF_TYPE_INT, M_OPT_RANGE, 0, 100, NULL}, 573 {"param", ST_OFF(param), CONF_TYPE_INT, M_OPT_RANGE, 0, 100, NULL},
535 // Note that here the 2 field is NULL (ie 0) 574 // Note that here the 2 field is NULL (ie 0)
536 // As we want this option to act on the option struct itself 575 // As we want this option to act on the option struct itself
537 {"presize", 0, CONF_TYPE_OBJ_PRESETS, 0, 0, 0, &size_preset}, 576 {"presize", 0, CONF_TYPE_OBJ_PRESETS, 0, 0, 0, &size_preset},