📄 mosaic.c
字号:
p_bridge = GetBridge( p_filter ); if ( p_bridge == NULL ) { vlc_mutex_unlock( p_sys->p_lock ); vlc_mutex_unlock( &p_sys->lock ); return p_spu; } if ( p_sys->i_position == 0 ) /* use automatic positioning */ { int i_numpics = p_sys->i_order_length; /* keep slots and all */ for ( i_index = 0; i_index < p_bridge->i_es_num; i_index++ ) { bridged_es_t *p_es = p_bridge->pp_es[i_index]; if ( !p_es->b_empty ) { i_numpics ++; if( p_sys->i_order_length && p_es->psz_id != 0 ) { /* We also want to leave slots for images given in * mosaic-order that are not available in p_vout_picture */ int i; for( i = 0; i < p_sys->i_order_length ; i++ ) { if( !strcmp( p_sys->ppsz_order[i], p_es->psz_id ) ) { i_numpics--; break; } } } } } p_sys->i_rows = ((int)ceil(sqrt( (float)i_numpics ))); p_sys->i_cols = ( i_numpics % p_sys->i_rows == 0 ? i_numpics / p_sys->i_rows : i_numpics / p_sys->i_rows + 1 ); } i_real_index = 0; for ( i_index = 0; i_index < p_bridge->i_es_num; i_index++ ) { bridged_es_t *p_es = p_bridge->pp_es[i_index]; video_format_t fmt_in = {0}, fmt_out = {0}; picture_t *p_converted; if ( p_es->b_empty || p_es->p_picture == NULL ) continue; if ( p_es->p_picture->date + p_sys->i_delay < date ) { if ( p_es->p_picture->p_next != NULL ) { picture_t *p_next = p_es->p_picture->p_next; p_es->p_picture->pf_release( p_es->p_picture ); p_es->p_picture = p_next; } else if ( p_es->p_picture->date + p_sys->i_delay + BLANK_DELAY < date ) { /* Display blank */ p_es->p_picture->pf_release( p_es->p_picture ); p_es->p_picture = NULL; p_es->pp_last = &p_es->p_picture; continue; } else msg_Dbg( p_filter, "too late picture for %s (" I64Fd ")", p_es->psz_id, date - p_es->p_picture->date - p_sys->i_delay ); } if ( p_sys->i_order_length == 0 ) { i_real_index++; } else { int i; for ( i = 0; i <= p_sys->i_order_length; i++ ) { if ( i == p_sys->i_order_length ) break; if ( strcmp( p_es->psz_id, p_sys->ppsz_order[i] ) == 0 ) { i_real_index = i; break; } } if ( i == p_sys->i_order_length ) i_real_index = ++i_greatest_real_index_used; } i_row = ( i_real_index / p_sys->i_cols ) % p_sys->i_rows; i_col = i_real_index % p_sys->i_cols ; if ( !p_sys->b_keep ) { /* Convert the images */ fmt_in.i_chroma = p_es->p_picture->format.i_chroma; fmt_in.i_height = p_es->p_picture->format.i_height; fmt_in.i_width = p_es->p_picture->format.i_width; fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A'); fmt_out.i_width = fmt_in.i_width * ( ( p_sys->i_width - ( p_sys->i_cols - 1 ) * p_sys->i_vborder ) / p_sys->i_cols ) / fmt_in.i_width; fmt_out.i_height = fmt_in.i_height * ( ( p_sys->i_height - ( p_sys->i_rows - 1 ) * p_sys->i_hborder ) / p_sys->i_rows ) / fmt_in.i_height; if( p_sys->b_ar ) /* keep aspect ratio */ { if( (float)fmt_out.i_width / (float)fmt_out.i_height > (float)fmt_in.i_width / (float)fmt_in.i_height ) { fmt_out.i_width = ( fmt_out.i_height * fmt_in.i_width ) / fmt_in.i_height; } else { fmt_out.i_height = ( fmt_out.i_width * fmt_in.i_height ) / fmt_in.i_width; } } fmt_out.i_visible_width = fmt_out.i_width; fmt_out.i_visible_height = fmt_out.i_height; p_converted = image_Convert( p_sys->p_image, p_es->p_picture, &fmt_in, &fmt_out ); if( !p_converted ) { msg_Warn( p_filter, "image resizing and chroma conversion failed" ); continue; } } else { p_converted = p_es->p_picture; p_converted->i_refcount++; fmt_in.i_width = fmt_out.i_width = p_converted->format.i_width; fmt_in.i_height = fmt_out.i_height = p_converted->format.i_height; fmt_in.i_chroma = fmt_out.i_chroma = p_converted->format.i_chroma; fmt_out.i_visible_width = fmt_out.i_width; fmt_out.i_visible_height = fmt_out.i_height; } p_region = p_spu->pf_make_region( VLC_OBJECT(p_filter), &fmt_out, p_converted ); if( !p_region ) { msg_Err( p_filter, "cannot allocate SPU region" ); p_filter->pf_sub_buffer_del( p_filter, p_spu ); vlc_mutex_unlock( &p_sys->lock ); vlc_mutex_unlock( p_sys->p_lock ); return p_spu; } /* HACK ALERT : let's fix the pointers to avoid picture duplication. * This is necessary because p_region->picture is not a pointer * as it ought to be. */ if( !p_sys->b_keep ) { free( p_converted ); } else { /* Keep a pointer to the original picture (and its refcount...). */ p_region->picture.p_sys = (picture_sys_t *)p_converted; p_region->picture.pf_release = MosaicReleasePicture; } if( p_sys->b_ar || p_sys->b_keep ) /* keep aspect ratio */ { /* center the video in the dedicated rectangle */ p_region->i_x = p_sys->i_xoffset + i_col * ( p_sys->i_width / p_sys->i_cols ) + ( i_col * p_sys->i_vborder ) / p_sys->i_cols + ( ( ( p_sys->i_width - ( p_sys->i_cols - 1 ) * p_sys->i_vborder ) / p_sys->i_cols ) - fmt_out.i_width ) / 2; p_region->i_y = p_sys->i_yoffset + i_row * ( p_sys->i_height / p_sys->i_rows ) + ( i_row * p_sys->i_hborder ) / p_sys->i_rows + ( ( ( p_sys->i_height - ( p_sys->i_rows - 1 ) * p_sys->i_hborder ) / p_sys->i_rows ) - fmt_out.i_height ) / 2; } else { /* we don't have to center the video since it takes the whole rectangle area */ p_region->i_x = p_sys->i_xoffset + i_col * ( p_sys->i_width / p_sys->i_cols ) + ( i_col * p_sys->i_vborder ) / p_sys->i_cols; p_region->i_y = p_sys->i_yoffset + i_row * ( p_sys->i_height / p_sys->i_rows ) + ( i_row * p_sys->i_hborder ) / p_sys->i_rows; } if( p_region_prev == NULL ) { p_spu->p_region = p_region; } else { p_region_prev->p_next = p_region; } p_region_prev = p_region; } vlc_mutex_unlock( p_sys->p_lock ); vlc_mutex_unlock( &p_sys->lock ); return p_spu;}/****************************************************************************** Callback to update params on the fly*****************************************************************************/static int MosaicCallback( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ filter_sys_t *p_sys = (filter_sys_t *) p_data; if( !strcmp( psz_var, "mosaic-alpha" ) ) { vlc_mutex_lock( &p_sys->lock ); msg_Dbg( p_this, "Changing alpha from %d/255 to %d/255", p_sys->i_alpha, newval.i_int); p_sys->i_alpha = __MIN( __MAX( newval.i_int, 0 ), 255 ); vlc_mutex_unlock( &p_sys->lock ); } else if( !strcmp( psz_var, "mosaic-height" ) ) { vlc_mutex_lock( &p_sys->lock ); msg_Dbg( p_this, "Changing height from %dpx to %dpx", p_sys->i_height, newval.i_int ); p_sys->i_height = __MAX( newval.i_int, 0 ); vlc_mutex_unlock( &p_sys->lock ); } else if( !strcmp( psz_var, "mosaic-width" ) ) { vlc_mutex_lock( &p_sys->lock ); msg_Dbg( p_this, "Changing width from %dpx to %dpx", p_sys->i_width, newval.i_int ); p_sys->i_width = __MAX( newval.i_int, 0 ); vlc_mutex_unlock( &p_sys->lock ); } else if( !strcmp( psz_var, "mosaic-xoffset" ) ) { vlc_mutex_lock( &p_sys->lock ); msg_Dbg( p_this, "Changing x offset from %dpx to %dpx", p_sys->i_xoffset, newval.i_int ); p_sys->i_xoffset = __MAX( newval.i_int, 0 ); vlc_mutex_unlock( &p_sys->lock ); } else if( !strcmp( psz_var, "mosaic-yoffset" ) ) { vlc_mutex_lock( &p_sys->lock ); msg_Dbg( p_this, "Changing y offset from %dpx to %dpx", p_sys->i_yoffset, newval.i_int ); p_sys->i_yoffset = __MAX( newval.i_int, 0 ); vlc_mutex_unlock( &p_sys->lock ); } else if( !strcmp( psz_var, "mosaic-align" ) ) { int i_old = 0, i_new = 0; vlc_mutex_lock( &p_sys->lock ); newval.i_int = __MIN( __MAX( newval.i_int, 0 ), 10 ); if( newval.i_int == 3 || newval.i_int == 7 ) newval.i_int = 5; while( pi_align_values[i_old] != p_sys->i_align ) i_old++; while( pi_align_values[i_new] != newval.i_int ) i_new++; msg_Dbg( p_this, "Changing alignment from %d (%s) to %d (%s)", p_sys->i_align, ppsz_align_descriptions[i_old], newval.i_int, ppsz_align_descriptions[i_new] ); p_sys->i_align = newval.i_int; vlc_mutex_unlock( &p_sys->lock ); } else if( !strcmp( psz_var, "mosaic-vborder" ) ) { vlc_mutex_lock( &p_sys->lock ); msg_Dbg( p_this, "Changing vertical border from %dpx to %dpx", p_sys->i_vborder, newval.i_int ); p_sys->i_vborder = __MAX( newval.i_int, 0 ); vlc_mutex_unlock( &p_sys->lock ); } else if( !strcmp( psz_var, "mosaic-hborder" ) ) { vlc_mutex_lock( &p_sys->lock ); msg_Dbg( p_this, "Changing horizontal border from %dpx to %dpx", p_sys->i_vborder, newval.i_int ); p_sys->i_hborder = __MAX( newval.i_int, 0 ); vlc_mutex_unlock( &p_sys->lock ); } else if( !strcmp( psz_var, "mosaic-position" ) ) { if( newval.i_int > 1 || newval.i_int < 0 ) { msg_Err( p_this, "Position is either 0 (auto) or 1 (fixed)" ); } else { vlc_mutex_lock( &p_sys->lock ); msg_Dbg( p_this, "Changing position method from %d (%s) to %d (%s)", p_sys->i_position, ppsz_pos_descriptions[p_sys->i_position], newval.i_int, ppsz_pos_descriptions[newval.i_int]); p_sys->i_position = newval.i_int; vlc_mutex_unlock( &p_sys->lock ); } } else if( !strcmp( psz_var, "mosaic-rows" ) ) { vlc_mutex_lock( &p_sys->lock ); msg_Dbg( p_this, "Changing number of rows from %d to %d", p_sys->i_rows, newval.i_int ); p_sys->i_rows = __MAX( newval.i_int, 1 ); vlc_mutex_unlock( &p_sys->lock ); } else if( !strcmp( psz_var, "mosaic-cols" ) ) { vlc_mutex_lock( &p_sys->lock ); msg_Dbg( p_this, "Changing number of columns from %d to %d", p_sys->i_cols, newval.i_int ); p_sys->i_cols = __MAX( newval.i_int, 1 ); vlc_mutex_unlock( &p_sys->lock ); } else if( !strcmp( psz_var, "mosaic-keep-aspect-ratio" ) ) { vlc_mutex_lock( &p_sys->lock ); if( newval.i_int ) { msg_Dbg( p_this, "Keep aspect ratio" ); p_sys->b_ar = 1; } else { msg_Dbg( p_this, "Don't keep aspect ratio" ); p_sys->b_ar = 0; } vlc_mutex_unlock( &p_sys->lock ); } return VLC_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -