Ejemplo n.º 1
0
Archivo: epg.c Proyecto: etix/vlc
bool vlc_epg_AddEvent( vlc_epg_t *p_epg, vlc_epg_event_t *p_evt )
{
    ssize_t i_pos = -1;

    /* Insertions are supposed in sequential order first */
    if( p_epg->i_event )
    {
        if( p_epg->pp_event[0]->i_start > p_evt->i_start )
        {
            i_pos = 0;
        }
        else if ( p_epg->pp_event[p_epg->i_event - 1]->i_start >= p_evt->i_start )
        {
            /* Do bisect search lower start time entry */
            size_t i_lower = 0;
            size_t i_upper = p_epg->i_event - 1;

            while( i_lower < i_upper )
            {
                size_t i_split = ( i_lower + i_upper ) / 2;
                vlc_epg_event_t *p_cur = p_epg->pp_event[i_split];

                if( p_cur->i_start < p_evt->i_start )
                {
                    i_lower = i_split + 1;
                }
                else if ( p_cur->i_start >= p_evt->i_start )
                {
                    i_upper = i_split;
                }
            }
            i_pos = i_lower;
        }
    }

    if( i_pos != -1 )
    {
        /* There can be only one event at same time */
        if( p_epg->pp_event[i_pos]->i_start == p_evt->i_start )
        {
            vlc_epg_event_Delete( p_epg->pp_event[i_pos] );
            if( p_epg->p_current == p_epg->pp_event[i_pos] )
                p_epg->p_current = p_evt;
            p_epg->pp_event[i_pos] = p_evt;
            return true;
        }
        else
        {
            TAB_INSERT( p_epg->i_event, p_epg->pp_event, p_evt, i_pos );
        }
    }
    else
        TAB_APPEND( p_epg->i_event, p_epg->pp_event, p_evt );

    return true;
}
Ejemplo n.º 2
0
/*****************************************************************************
 * Import cut marks and convert them to seekpoints (chapters).
 *****************************************************************************/
static void ImportMarks( access_t *p_access )
{
    access_sys_t *p_sys = p_access->p_sys;

    FILE *marksfile = OpenRelativeFile( p_access, "marks" );
    if( !marksfile )
        return;

    FILE *indexfile = OpenRelativeFile( p_access, "index" );
    if( !indexfile )
    {
        fclose( marksfile );
        return;
    }

    /* get the length of this recording (index stores 8 bytes per frame) */
    struct stat st;
    if( fstat( fileno( indexfile ), &st ) )
    {
        fclose( marksfile );
        fclose( indexfile );
        return;
    }
    int64_t i_frame_count = st.st_size / 8;

    /* Put all cut marks in a "dummy" title */
    input_title_t *p_marks = vlc_input_title_New();
    if( !p_marks )
    {
        fclose( marksfile );
        fclose( indexfile );
        return;
    }
    p_marks->psz_name = strdup( _("VDR Cut Marks") );
    p_marks->i_length = i_frame_count * (int64_t)( CLOCK_FREQ / p_sys->fps );

    uint64_t *offsetv = NULL;
    size_t offsetc = 0;

    /* offset for chapter positions */
    int i_chapter_offset = p_sys->fps / 1000 *
        var_InheritInteger( p_access, "vdr-chapter-offset" );

    /* minimum chapter size in frames */
    int i_min_chapter_size = p_sys->fps * MIN_CHAPTER_SIZE;

    /* the last chapter started at this frame (init to 0 so
     * we skip useless chapters near the beginning as well) */
    int64_t i_prev_chapter = 0;

    /* parse lines of the form "0:00:00.00 foobar" */
    char *line = NULL;
    size_t line_len;
    while( ReadLine( &line, &line_len, marksfile ) )
    {
        int64_t i_frame = ParseFrameNumber( line, p_sys->fps );

        /* skip chapters which are near the end or too close to each other */
        if( i_frame - i_prev_chapter < i_min_chapter_size ||
            i_frame >= i_frame_count - i_min_chapter_size )
            continue;
        i_prev_chapter = i_frame;

        /* move chapters (simple workaround for inaccurate cut marks) */
        if( i_frame > -i_chapter_offset )
            i_frame += i_chapter_offset;
        else
            i_frame = 0;

        uint64_t i_offset;
        uint16_t i_file_number;
        if( !ReadIndexRecord( indexfile, p_sys->b_ts_format,
            i_frame, &i_offset, &i_file_number ) )
            continue;
        if( i_file_number < 1 || i_file_number > FILE_COUNT )
            continue;

        /* add file sizes to get the "global" offset */
        seekpoint_t *sp = vlc_seekpoint_New();
        if( !sp )
            continue;
        sp->i_time_offset = i_frame * (int64_t)( CLOCK_FREQ / p_sys->fps );
        sp->psz_name = strdup( line );

        TAB_APPEND( p_marks->i_seekpoint, p_marks->seekpoint, sp );
        TAB_APPEND( offsetc, offsetv, i_offset );

        for( int i = 0; i + 1 < i_file_number; ++i )
            offsetv[offsetc - 1] += FILE_SIZE( i );
    }

    /* add a chapter at the beginning if missing */
    if( p_marks->i_seekpoint > 0 && offsetv[0] > 0 )
    {
        seekpoint_t *sp = vlc_seekpoint_New();
        if( sp )
        {
            sp->i_time_offset = 0;
            sp->psz_name = strdup( _("Start") );
            TAB_INSERT( p_marks->i_seekpoint, p_marks->seekpoint, sp, 0 );
            TAB_INSERT( offsetc, offsetv, UINT64_C(0), 0 );
        }
    }

    if( p_marks->i_seekpoint > 0 )
    {
        p_sys->p_marks = p_marks;
        p_sys->offsets = offsetv;
    }
    else
    {
        vlc_input_title_Delete( p_marks );
        TAB_CLEAN( offsetc, offsetv );
    }

    fclose( marksfile );
    fclose( indexfile );
}
Ejemplo n.º 3
0
Archivo: epg.c Proyecto: etix/vlc
void vlc_epg_Merge( vlc_epg_t *p_dst_epg, const vlc_epg_t *p_src_epg )
{
    if( p_src_epg->i_event == 0 )
        return;

    size_t i_dst=0;
    size_t i_src=0;
    for( ; i_src < p_src_epg->i_event; i_src++ )
    {
        bool b_current = ( p_src_epg->pp_event[i_src] == p_src_epg->p_current );

        vlc_epg_event_t *p_src = vlc_epg_event_Duplicate( p_src_epg->pp_event[i_src] );
        if( unlikely(!p_src) )
            return;
        const int64_t i_src_end = p_src->i_start + p_src->i_duration;

        while( i_dst < p_dst_epg->i_event )
        {
            vlc_epg_event_t *p_dst = p_dst_epg->pp_event[i_dst];
            const int64_t i_dst_end = p_dst->i_start + p_dst->i_duration;

            /* appended is before current, no overlap */
            if( p_dst->i_start >= i_src_end )
            {
                break;
            }
            /* overlap case: appended would contain current's start (or are identical) */
            else if( ( p_dst->i_start >= p_src->i_start && p_dst->i_start < i_src_end ) ||
            /* overlap case: appended would contain current's end */
                    ( i_dst_end > p_src->i_start && i_dst_end <= i_src_end ) )
            {
                vlc_epg_event_Delete( p_dst );
                if( p_dst_epg->p_current == p_dst )
                {
                    b_current |= true;
                    p_dst_epg->p_current = NULL;
                }
                TAB_ERASE( p_dst_epg->i_event, p_dst_epg->pp_event, i_dst );
            }
            else
            {
                i_dst++;
            }
        }

        TAB_INSERT( p_dst_epg->i_event, p_dst_epg->pp_event, p_src, i_dst );
        if( b_current )
            p_dst_epg->p_current = p_src;
    }

    /* Remaining/trailing ones */
    for( ; i_src < p_src_epg->i_event; i_src++ )
    {
        vlc_epg_event_t *p_src = vlc_epg_event_Duplicate( p_src_epg->pp_event[i_src] );
        if( unlikely(!p_src) )
            return;
        TAB_APPEND( p_dst_epg->i_event, p_dst_epg->pp_event, p_src );
        if( p_src_epg->pp_event[i_src] == p_src_epg->p_current )
            p_dst_epg->p_current = p_src;
    }

    vlc_epg_Prune( p_dst_epg );
}
Ejemplo n.º 4
0
Archivo: epg.c Proyecto: 0xheart0/vlc
void vlc_epg_AddEvent( vlc_epg_t *p_epg, int64_t i_start, int i_duration,
                       const char *psz_name, const char *psz_short_description,
                       const char *psz_description, uint8_t i_rating )
{
    vlc_epg_event_t *p_evt = vlc_epg_Event_New( i_start, i_duration,
                                                psz_name, psz_short_description,
                                                psz_description, i_rating );
    if( unlikely(!p_evt) )
        return;

    int i_pos = -1;

    /* Insertions are supposed in sequential order first */
    if( p_epg->i_event )
    {
        if( p_epg->pp_event[0]->i_start > i_start )
        {
            i_pos = 0;
        }
        else if ( p_epg->pp_event[p_epg->i_event - 1]->i_start >= i_start )
        {
            /* Do bisect search lower start time entry */
            int i_lower = 0;
            int i_upper = p_epg->i_event - 1;

            while( i_lower < i_upper )
            {
                int i_split = ( (size_t)i_lower + i_upper ) / 2;
                vlc_epg_event_t *p_cur = p_epg->pp_event[i_split];

                if( p_cur->i_start < i_start )
                {
                    i_lower = i_split + 1;
                }
                else if ( p_cur->i_start >= i_start )
                {
                    i_upper = i_split;
                }
            }
            i_pos = i_lower;
        }
    }

    if( i_pos != -1 )
    {
        if( p_epg->pp_event[i_pos]->i_start == i_start )/* There can be only one event at same time */
        {
            vlc_epg_Event_Delete( p_epg->pp_event[i_pos] );
            if( p_epg->p_current == p_epg->pp_event[i_pos] )
                p_epg->p_current = p_evt;
            p_epg->pp_event[i_pos] = p_evt;
            return;
        }
        else
        {
            TAB_INSERT( p_epg->i_event, p_epg->pp_event, p_evt, i_pos );
        }
    }
    else
        TAB_APPEND( p_epg->i_event, p_epg->pp_event, p_evt );
}