📄 mosaic.c
字号:
p_sys->i_order_length = 0; p_sys->ppsz_order = NULL; psz_order = var_CreateGetString( p_filter, "mosaic-order" ); if( psz_order[0] != 0 ) { char *psz_end = NULL; i_index = 0; do { psz_end = strchr( psz_order, ',' ); i_index++; p_sys->ppsz_order = realloc( p_sys->ppsz_order, i_index * sizeof(char *) ); p_sys->ppsz_order[i_index - 1] = strndup( psz_order, psz_end - psz_order ); psz_order = psz_end+1; } while( NULL != psz_end ); p_sys->i_order_length = i_index; } /* Bluescreen specific stuff */ GET_VAR( bsu, 0x00, 0xff ); GET_VAR( bsv, 0x00, 0xff ); GET_VAR( bsut, 0x00, 0xff ); GET_VAR( bsvt, 0x00, 0xff ); p_sys->b_bs = var_CreateGetBool( p_filter, "mosaic-bs" ); var_Destroy( p_filter, "mosaic-bs" ); var_Create( p_libvlc, "mosaic-bs", VLC_VAR_INTEGER ); var_SetBool( p_libvlc, "mosaic-bs", p_sys->b_bs ); var_AddCallback( p_libvlc, "mosaic-bs", MosaicCallback, p_sys ); if( p_sys->b_bs && p_sys->b_keep ) { msg_Warn( p_filter, "mosaic-keep-picture needs to be disabled for" " bluescreen to work" ); } vlc_mutex_unlock( &p_sys->lock ); return VLC_SUCCESS;}/***************************************************************************** * DestroyFilter: destroy mosaic video filter *****************************************************************************/static void DestroyFilter( vlc_object_t *p_this ){ filter_t *p_filter = (filter_t*)p_this; filter_sys_t *p_sys = p_filter->p_sys; libvlc_t *p_libvlc = p_filter->p_libvlc; int i_index; vlc_mutex_lock( &p_sys->lock ); if( !p_sys->b_keep ) { image_HandlerDelete( p_sys->p_image ); } if( p_sys->i_order_length ) { for( i_index = 0; i_index < p_sys->i_order_length; i_index++ ) { free( p_sys->ppsz_order[i_index] ); } free( p_sys->ppsz_order ); } var_Destroy( p_libvlc, "mosaic-alpha" ); var_Destroy( p_libvlc, "mosaic-height" ); var_Destroy( p_libvlc, "mosaic-align" ); var_Destroy( p_libvlc, "mosaic-width" ); var_Destroy( p_libvlc, "mosaic-xoffset" ); var_Destroy( p_libvlc, "mosaic-yoffset" ); var_Destroy( p_libvlc, "mosaic-borderw" ); var_Destroy( p_libvlc, "mosaic-borderh" ); var_Destroy( p_libvlc, "mosaic-position" ); var_Destroy( p_libvlc, "mosaic-rows" ); var_Destroy( p_libvlc, "mosaic-cols" ); var_Destroy( p_libvlc, "mosaic-keep-aspect-ratio" ); var_Destroy( p_libvlc, "mosaic-bsu" ); var_Destroy( p_libvlc, "mosaic-bsv" ); var_Destroy( p_libvlc, "mosaic-bsut" ); var_Destroy( p_libvlc, "mosaic-bsvt" ); var_Destroy( p_libvlc, "mosaic-bs" ); if( p_sys->p_pic ) p_sys->p_pic->pf_release( p_sys->p_pic ); vlc_mutex_unlock( &p_sys->lock ); vlc_mutex_destroy( &p_sys->lock ); free( p_sys );}/***************************************************************************** * MosaicReleasePicture : Hack to avoid picture duplication *****************************************************************************/static void MosaicReleasePicture( picture_t *p_picture ){ picture_t *p_original_pic = (picture_t *)p_picture->p_sys; p_original_pic->pf_release( p_original_pic );}/***************************************************************************** * Filter *****************************************************************************/static subpicture_t *Filter( filter_t *p_filter, mtime_t date ){ filter_sys_t *p_sys = p_filter->p_sys; bridge_t *p_bridge; subpicture_t *p_spu; int i_index, i_real_index, i_row, i_col; int i_greatest_real_index_used = p_sys->i_order_length - 1; unsigned int col_inner_width, row_inner_height; subpicture_region_t *p_region; subpicture_region_t *p_region_prev = NULL; /* Allocate the subpicture internal data. */ p_spu = p_filter->pf_sub_buffer_new( p_filter ); if( !p_spu ) { return NULL; } /* Initialize subpicture */ p_spu->i_channel = 0; p_spu->i_start = date; p_spu->i_stop = 0; p_spu->b_ephemer = VLC_TRUE; p_spu->i_alpha = p_sys->i_alpha; p_spu->i_flags = p_sys->i_align; p_spu->b_absolute = VLC_FALSE; vlc_mutex_lock( &p_sys->lock ); vlc_mutex_lock( p_sys->p_lock ); 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 ); } col_inner_width = ( ( p_sys->i_width - ( p_sys->i_cols - 1 ) * p_sys->i_borderw ) / p_sys->i_cols ); row_inner_height = ( ( p_sys->i_height - ( p_sys->i_rows - 1 ) * p_sys->i_borderh ) / p_sys->i_rows ); 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 ) continue; while ( p_es->p_picture != NULL && 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; break; } 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 ); break; } } if ( p_es->p_picture == NULL ) continue; 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 = col_inner_width; fmt_out.i_height = row_inner_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; } /* Bluescreen stuff */ if( p_sys->b_bs ) { int i,j; int i_lines = p_converted->p[ A_PLANE ].i_lines; int i_pitch = p_converted->p[ A_PLANE ].i_pitch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -