Changeset 350148d32c57a849a34dd44df89058b41f28531c
- Timestamp:
- 06/04/08 13:14:12 (3 months ago)
- git-parent:
- Files:
-
- include/vlc_vout.h (modified) (12 diffs)
- src/video_output/video_output.c (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
include/vlc_vout.h
r2e2178f r350148d 32 32 33 33 #include <vlc_es.h> 34 #include <vlc_filter.h> 34 35 35 36 /** Description of a planar graphic field */ … … 79 80 int i_status; /**< picture flags */ 80 81 int i_type; /**< is picture a direct buffer ? */ 81 bool b_slow; /**< is picture in slow memory ? */82 bool b_slow; /**< is picture in slow memory ? */ 82 83 int i_matrix_coefficients; /**< in YUV type, encoding type */ 83 84 /**@}*/ … … 89 90 unsigned i_refcount; /**< link reference counter */ 90 91 mtime_t date; /**< display date */ 91 bool b_force;92 bool b_force; 92 93 /**@}*/ 93 94 … … 96 97 * @{ 97 98 */ 98 bool b_progressive; /**< is it a progressive frame ? */99 bool b_progressive; /**< is it a progressive frame ? */ 99 100 unsigned int i_nb_fields; /**< # of displayed fields */ 100 bool b_top_field_first; /**< which field is first */101 bool b_top_field_first; /**< which field is first */ 101 102 /**@}*/ 102 103 … … 140 141 picture_t* pp_picture[VOUT_MAX_PICTURES]; /**< pictures */ 141 142 int i_last_used_pic; /**< last used pic in heap */ 142 bool b_allow_modify_pics;143 bool b_allow_modify_pics; 143 144 144 145 /* Stuff used for truecolor RGB planes */ … … 249 250 mtime_t i_start; /**< beginning of display date */ 250 251 mtime_t i_stop; /**< end of display date */ 251 bool b_ephemer; /**< If this flag is set to true the subtitle252 bool b_ephemer; /**< If this flag is set to true the subtitle 252 253 will be displayed untill the next one appear */ 253 bool b_fade; /**< enable fading */254 bool b_pausable; /**< subpicture will be paused if254 bool b_fade; /**< enable fading */ 255 bool b_pausable; /**< subpicture will be paused if 255 256 stream is paused */ 256 257 /**@}*/ … … 270 271 int i_original_picture_width; /**< original width of the movie */ 271 272 int i_original_picture_height;/**< original height of the movie */ 272 bool b_absolute; /**< position is absolute */273 bool b_absolute; /**< position is absolute */ 273 274 int i_flags; /**< position flags */ 274 275 /**@}*/ … … 366 367 */ 367 368 368 /** Maximum numbers of video filters2 that can be attached to a vout */369 #define MAX_VFILTERS 10370 371 369 /** 372 370 * Video output thread descriptor … … 394 392 \see \ref vout_changes */ 395 393 float f_gamma; /**< gamma */ 396 bool b_grayscale; /**< color or grayscale display */397 bool b_info; /**< print additional information */398 bool b_interface; /**< render interface */399 bool b_scale; /**< allow picture scaling */400 bool b_fullscreen; /**< toogle fullscreen display */394 bool b_grayscale; /**< color or grayscale display */ 395 bool b_info; /**< print additional information */ 396 bool b_interface; /**< render interface */ 397 bool b_scale; /**< allow picture scaling */ 398 bool b_fullscreen; /**< toogle fullscreen display */ 401 399 uint32_t render_time; /**< last picture render time */ 402 400 unsigned int i_window_width; /**< video window width */ … … 437 435 picture_heap_t render; /**< rendered pictures */ 438 436 picture_heap_t output; /**< direct buffers */ 439 bool b_direct; /**< rendered are like direct ? */440 filter_t *p_chroma;/**< translation tables */437 bool b_direct; /**< rendered are like direct ? */ 438 filter_t *p_chroma; /**< translation tables */ 441 439 442 440 video_format_t fmt_render; /* render format (from the decoder) */ … … 449 447 450 448 /* Subpicture unit */ 451 spu_t *p_spu;449 spu_t *p_spu; 452 450 453 451 /* Statistics */ 454 count_t c_loops;455 count_t c_pictures, c_late_pictures;456 mtime_t display_jitter; /**< average deviation from the PTS */457 count_t c_jitter_samples; /**< number of samples used452 count_t c_loops; 453 count_t c_pictures, c_late_pictures; 454 mtime_t display_jitter; /**< average deviation from the PTS */ 455 count_t c_jitter_samples; /**< number of samples used 458 456 for the calculation of the 459 457 jitter */ 460 458 /** delay created by internal caching */ 461 int i_pts_delay;459 int i_pts_delay; 462 460 463 461 /* Filter chain */ 464 char *psz_filter_chain; 465 bool b_filter_change; 466 467 /* Video filter2 chain 468 * these are handled like in transcode.c 469 * XXX: we might need to merge the two chains (v1 and v2 filters) */ 470 char *psz_vfilters[MAX_VFILTERS]; 471 config_chain_t *p_vfilters_cfg[MAX_VFILTERS]; 472 int i_vfilters_cfg; 473 474 filter_t *pp_vfilters[MAX_VFILTERS]; 475 int i_vfilters; 476 477 bool b_vfilter_change; 462 char *psz_filter_chain; 463 bool b_filter_change; 464 465 /* Video filter2 chain */ 466 filter_chain_t *p_vf2_chain; 467 char *psz_vf2; 478 468 479 469 /* Misc */ 480 bool b_snapshot; /**< take one snapshot on the next loop */470 bool b_snapshot; /**< take one snapshot on the next loop */ 481 471 482 472 /* Video output configuration */ … … 484 474 485 475 /* Show media title on videoutput */ 486 bool b_title_show;476 bool b_title_show; 487 477 mtime_t i_title_timeout; 488 478 int i_title_position; src/video_output/video_output.c
r218efb9 r350148d 85 85 int vout_Snapshot( vout_thread_t *, picture_t * ); 86 86 87 /* Video filter2 parsing */88 static int ParseVideoFilter2Chain( vout_thread_t *, char * );89 static void RemoveVideoFilters2( vout_thread_t *p_vout );90 91 87 /* Display media title in OSD */ 92 88 static void DisplayTitleOnOSD( vout_thread_t *p_vout ); … … 95 91 * Video Filter2 functions 96 92 *****************************************************************************/ 97 struct filter_owner_sys_t98 {99 vout_thread_t *p_vout;100 };101 102 93 static picture_t *video_new_buffer_filter( filter_t *p_filter ) 103 94 { 104 95 picture_t *p_picture; 105 vout_thread_t *p_vout = p_filter->p_owner->p_vout;96 vout_thread_t *p_vout = (vout_thread_t*)p_filter->p_owner; 106 97 107 98 p_picture = vout_CreatePicture( p_vout, 0, 0, 0 ); … … 112 103 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic ) 113 104 { 114 vout_DestroyPicture( p_filter->p_owner->p_vout, p_pic ); 105 vout_DestroyPicture( (vout_thread_t*)p_filter->p_owner, p_pic ); 106 } 107 108 static int video_filter_buffer_allocation_init( filter_t *p_filter, void *p_data ) 109 { 110 p_filter->pf_vout_buffer_new = video_new_buffer_filter; 111 p_filter->pf_vout_buffer_del = video_del_buffer_filter; 112 p_filter->p_owner = p_data; /* p_vout */ 113 return VLC_SUCCESS; 115 114 } 116 115 … … 343 342 { 344 343 /* Look for the default filter configuration */ 345 var_Create( p_vout, "vout-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); 346 var_Get( p_vout, "vout-filter", &val ); 347 p_vout->psz_filter_chain = val.psz_string; 344 p_vout->psz_filter_chain = 345 var_CreateGetStringCommand( p_vout, "vout-filter" ); 348 346 349 347 /* Apply video filter2 objects on the first vout */ 350 var_Create( p_vout, "video-filter", 351 VLC_VAR_STRING | VLC_VAR_DOINHERIT ); 352 var_Get( p_vout, "video-filter", &val ); 353 ParseVideoFilter2Chain( p_vout, val.psz_string ); 354 free( val.psz_string ); 348 p_vout->psz_vf2 = 349 var_CreateGetStringCommand( p_vout, "video-filter" ); 355 350 } 356 351 else … … 368 363 369 364 /* Create a video filter2 var ... but don't inherit values */ 370 var_Create( p_vout, "video-filter", VLC_VAR_STRING ); 371 ParseVideoFilter2Chain( p_vout, NULL ); 365 var_Create( p_vout, "video-filter", 366 VLC_VAR_STRING | VLC_VAR_ISCOMMAND ); 367 p_vout->psz_vf2 = var_GetString( p_vout, "video-filter" ); 372 368 } 373 369 374 370 var_AddCallback( p_vout, "video-filter", VideoFilter2Callback, NULL ); 375 p_vout-> b_vfilter_change = true;376 p_vout->i_vfilters = 0;371 p_vout->p_vf2_chain = filter_chain_New( p_vout, "video filter2", 372 false, video_filter_buffer_allocation_init, NULL, p_vout ); 377 373 378 374 /* Choose the video output module */ … … 957 953 958 954 /* Video Filter2 stuff */ 959 if( p_vout->b_vfilter_change == true ) 960 { 961 int i; 955 if( p_vout->psz_vf2 ) 956 { 957 es_format_t fmt; 958 962 959 vlc_mutex_lock( &p_vout->vfilter_lock ); 963 RemoveVideoFilters2( p_vout ); 964 for( i = 0; i < p_vout->i_vfilters_cfg; i++ ) 965 { 966 filter_t *p_vfilter = 967 p_vout->pp_vfilters[p_vout->i_vfilters] = 968 vlc_object_create( p_vout, VLC_OBJECT_FILTER ); 969 970 vlc_object_attach( p_vfilter, p_vout ); 971 972 p_vfilter->pf_vout_buffer_new = video_new_buffer_filter; 973 p_vfilter->pf_vout_buffer_del = video_del_buffer_filter; 974 975 if( !p_vout->i_vfilters ) 976 { 977 p_vfilter->fmt_in.video = p_vout->fmt_render; 978 } 979 else 980 { 981 p_vfilter->fmt_in.video = (p_vfilter-1)->fmt_out.video; 982 } 983 /* TODO: one day filters in the middle of the chain might 984 * have a different fmt_out.video than fmt_render ... */ 985 p_vfilter->fmt_out.video = p_vout->fmt_render; 986 987 p_vfilter->p_cfg = p_vout->p_vfilters_cfg[i]; 988 p_vfilter->p_module = module_Need( p_vfilter, "video filter2", 989 p_vout->psz_vfilters[i], 990 true ); 991 992 if( p_vfilter->p_module ) 993 { 994 p_vfilter->p_owner = 995 malloc( sizeof( filter_owner_sys_t ) ); 996 p_vfilter->p_owner->p_vout = p_vout; 997 p_vout->i_vfilters++; 998 msg_Dbg( p_vout, "video filter found (%s)", 999 p_vout->psz_vfilters[i] ); 1000 } 1001 else 1002 { 1003 msg_Err( p_vout, "no video filter found (%s)", 1004 p_vout->psz_vfilters[i] ); 1005 vlc_object_detach( p_vfilter ); 1006 vlc_object_release( p_vfilter ); 1007 } 1008 } 1009 p_vout->b_vfilter_change = false; 960 961 es_format_Init( &fmt, VIDEO_ES, p_vout->fmt_render.i_chroma ); 962 fmt.video = p_vout->fmt_render; 963 filter_chain_Reset( p_vout->p_vf2_chain, &fmt, &fmt ); 964 965 if( filter_chain_AppendFromString( p_vout->p_vf2_chain, 966 p_vout->psz_vf2 ) < 0 ) 967 msg_Err( p_vout, "Video filter chain creation failed" ); 968 969 else 970 { 971 free( p_vout->psz_vf2 ); 972 p_vout->psz_vf2 = NULL; 973 } 1010 974 vlc_mutex_unlock( &p_vout->vfilter_lock ); 1011 975 } … … 1013 977 if( p_picture ) 1014 978 { 1015 int i; 1016 for( i = 0; i < p_vout->i_vfilters; i++ ) 1017 { 1018 picture_t *p_old = p_picture; 1019 p_picture = p_vout->pp_vfilters[i]->pf_video_filter( 1020 p_vout->pp_vfilters[i], p_picture ); 1021 if( !p_picture ) 1022 { 1023 break; 1024 } 1025 /* FIXME: this is kind of wrong 1026 * if you have 2 or more vfilters and the 2nd breaks, 1027 * on the next loop the 1st one will be applied again */ 1028 1029 /* if p_old and p_picture are the same (ie the filter 1030 * worked on the old picture), then following code is 1031 * still alright since i_status gets changed back to 1032 * the right value */ 1033 if( p_old->i_refcount ) 1034 { 1035 p_old->i_status = DISPLAYED_PICTURE; 1036 } 1037 else 1038 { 1039 p_old->i_status = DESTROYED_PICTURE; 1040 } 1041 p_picture->i_status = READY_PICTURE; 1042 } 979 p_picture = filter_chain_VideoFilter( p_vout->p_vf2_chain, 980 p_picture ); 1043 981 } 1044 982 … … 1294 1232 1295 1233 /* Destroy the video filters2 */ 1296 RemoveVideoFilters2( p_vout);1234 filter_chain_Delete( p_vout->p_vf2_chain ); 1297 1235 1298 1236 /* Destroy translation tables */ … … 1551 1489 * Video Filter2 stuff 1552 1490 *****************************************************************************/ 1553 static int ParseVideoFilter2Chain( vout_thread_t *p_vout, char *psz_vfilters )1554 {1555 int i;1556 for( i = 0; i < p_vout->i_vfilters_cfg; i++ )1557 {1558 struct config_chain_t *p_cfg =1559 p_vout->p_vfilters_cfg[p_vout->i_vfilters_cfg];1560 config_ChainDestroy( p_cfg );1561 free( p_vout->psz_vfilters[p_vout->i_vfilters_cfg] );1562 p_vout->psz_vfilters[p_vout->i_vfilters_cfg] = NULL;1563 }1564 p_vout->i_vfilters_cfg = 0;1565 if( psz_vfilters && *psz_vfilters )1566 {1567 char *psz_parser = psz_vfilters;1568 1569 while( psz_parser && *psz_parser )1570 {1571 psz_parser = config_ChainCreate(1572 &p_vout->psz_vfilters[p_vout->i_vfilters_cfg],1573 &p_vout->p_vfilters_cfg[p_vout->i_vfilters_cfg],1574 psz_parser );1575 msg_Dbg( p_vout, "adding vfilter: %s",1576 p_vout->psz_vfilters[p_vout->i_vfilters_cfg] );1577 p_vout->i_vfilters_cfg++;1578 if( psz_parser && *psz_parser )1579 {1580 if( p_vout->i_vfilters_cfg == MAX_VFILTERS )1581 {1582 msg_Warn( p_vout,1583 "maximum number of video filters reached. \"%s\" discarded",1584 psz_parser );1585 break;1586 }1587 }1588 }1589 }1590 return VLC_SUCCESS;1591 }1592 1593 1491 static int VideoFilter2Callback( vlc_object_t *p_this, char const *psz_cmd, 1594 1492 vlc_value_t oldval, vlc_value_t newval, void *p_data ) … … 1598 1496 1599 1497 vlc_mutex_lock( &p_vout->vfilter_lock ); 1600 ParseVideoFilter2Chain( p_vout, newval.psz_string ); 1601 p_vout->b_vfilter_change = true; 1498 p_vout->psz_vf2 = strdup( newval.psz_string ); 1602 1499 vlc_mutex_unlock( &p_vout->vfilter_lock ); 1603 1500 1604 1501 return VLC_SUCCESS; 1605 }1606 1607 static void RemoveVideoFilters2( vout_thread_t *p_vout )1608 {1609 int i;1610 for( i = 0; i < p_vout->i_vfilters; i++ )1611 {1612 vlc_object_detach( p_vout->pp_vfilters[i] );1613 if( p_vout->pp_vfilters[i]->p_module )1614 {1615 module_Unneed( p_vout->pp_vfilters[i],1616 p_vout->pp_vfilters[i]->p_module );1617 }1618 1619 free( p_vout->pp_vfilters[i]->p_owner );1620 vlc_object_release( p_vout->pp_vfilters[i] );1621 }1622 p_vout->i_vfilters = 0;1623 1502 } 1624 1503
