Mercurial > mplayer.hg
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}, |