/***************************************************************************** * SubsdelayFilter: Filter new subpicture *****************************************************************************/ static subpicture_t * SubsdelayFilter( filter_t *p_filter, subpicture_t* p_subpic ) { subsdelay_heap_t *p_heap; subsdelay_heap_entry_t *p_entry; if( !p_subpic->b_subtitle ) { return p_subpic; } if( SubpicIsEmpty( p_subpic ) ) { /* empty subtitles usually helps terminate ephemer subtitles, but this filter calculates the stop value anyway, so this subtitle can be dropped */ subpicture_Delete( p_subpic ); return NULL; } p_heap = &p_filter->p_sys->heap; /* add subpicture to the heap */ SubsdelayHeapLock( p_heap ); p_entry = SubsdelayHeapPush( p_heap, p_subpic, p_filter ); if( !p_entry ) { SubsdelayHeapUnlock( p_heap ); msg_Err(p_filter, "Can't add subpicture to the heap"); return p_subpic; } p_subpic = p_entry->p_subpic; /* get the local subpic */ if( p_subpic->b_ephemer ) { /* set a relativly long delay in hope that the next subtitle will arrive in this time and the real delay could be determined */ p_subpic->i_stop = p_subpic->i_start + 20000000; /* start + 20 sec */ p_subpic->b_ephemer = false; } SubsdelayEnforceDelayRules( p_filter ); SubsdelayHeapUnlock( p_heap ); return p_subpic; }
/***************************************************************************** * SubsdelayRecalculateDelays: Recalculate subtitles delay after changing * one of the filter's parameters *****************************************************************************/ static void SubsdelayRecalculateDelays( filter_t *p_filter ) { for( subsdelay_heap_entry_t *p_curr = p_filter->p_sys->heap.p_head; p_curr != NULL; p_curr = p_curr->p_next ) { if( !p_curr->b_update_ephemer ) { p_curr->i_new_stop = p_curr->p_source->i_start + SubsdelayEstimateDelay( p_filter, p_curr ); p_curr->b_update_stop = false; } } SubsdelayEnforceDelayRules( p_filter ); }
/***************************************************************************** * SubpicLocalUpdate: rewrite some of the subpicture parameters *****************************************************************************/ static void SubpicLocalUpdate( subpicture_t* p_subpic, mtime_t i_ts ) { subsdelay_heap_entry_t *p_entry; subsdelay_heap_t *p_heap; filter_t *p_filter; int i_overlapping; p_entry = p_subpic->updater.p_sys; if( !p_entry || !p_entry->p_filter ) { return; } p_filter = p_entry->p_filter; p_heap = &p_filter->p_sys->heap; SubsdelayHeapLock( p_heap ); if( p_entry->b_check_empty && p_subpic->p_region ) { if( SubsdelayIsTextEmpty( p_subpic->p_region->psz_html ) || SubsdelayIsTextEmpty( p_subpic->p_region->psz_text ) ) { /* remove empty subtitle */ p_subpic->b_ephemer = false; p_subpic->i_stop = p_subpic->i_start; SubsdelayHeapRemove( p_heap, p_entry ); SubsdelayHeapUnlock( p_heap ); return; } p_entry->b_check_empty = false; } if( p_entry->b_update_stop && !p_entry->b_update_ephemer ) { p_entry->i_new_stop = p_entry->p_source->i_start + SubsdelayEstimateDelay( p_filter, p_entry ); p_entry->b_update_stop = false; SubsdelayEnforceDelayRules( p_filter ); } i_overlapping = SubsdelayHeapCountOverlap( p_heap, p_entry, i_ts ); p_subpic->i_alpha = SubsdelayCalculateAlpha( p_filter, i_overlapping, p_entry->p_source->i_alpha ); if( p_entry->b_update_position ) { p_subpic->b_absolute = false; if( p_subpic->p_region ) { p_subpic->p_region->i_x = 0; p_subpic->p_region->i_y = 10; p_subpic->p_region->i_align = ( p_subpic->p_region->i_align & ( ~SUBPICTURE_ALIGN_MASK ) ) | SUBPICTURE_ALIGN_BOTTOM; } p_entry->b_update_position = false; } else if( p_entry->b_last_region_saved ) { p_subpic->b_absolute = true; if( p_subpic->p_region ) { p_subpic->p_region->i_x = p_entry->i_last_region_x; p_subpic->p_region->i_y = p_entry->i_last_region_y; p_subpic->p_region->i_align = p_entry->i_last_region_align; } } SubsdelayHeapUnlock( p_heap ); }