⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp4.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                        continue;                    }                    if( !strncmp( psz_ref, "http://", 7 ) ||                        !strncmp( psz_ref, "rtsp://", 7 ) )                    {                        ;                    }                    else                    {                        char *psz_absolute;                        char *psz_path = strdup( p_demux->psz_path );                        char *end = strrchr( psz_path, '/' );                        if( end ) end[1] = '\0';                        else *psz_path = '\0';                        asprintf( &psz_absolute, "%s://%s%s",                                       p_demux->psz_access, psz_path, psz_ref );                        if( psz_ref ) free( psz_ref );                        psz_ref = psz_absolute;                        free( psz_path );                    }                    msg_Dbg( p_demux, "adding ref = `%s'", psz_ref );                    if( p_item )                    {                        playlist_item_t *p_child =                                    playlist_ItemNew( p_playlist,                                                      psz_ref, psz_ref );                        if( p_child )                        {                            playlist_NodeAddItem( p_playlist, p_child,                                             p_item->pp_parents[0]->i_view,                                             p_item, PLAYLIST_APPEND,                                             PLAYLIST_END );                            playlist_CopyParents( p_item, p_child );                            b_play = VLC_TRUE;                        }                    }                }                else                {                    msg_Err( p_demux, "unknown ref type=%4.4s FIXME (send a bug report)",                             (char*)&p_rdrf->data.p_rdrf->i_ref_type );                }                if( psz_ref ) free( psz_ref );            }            if( b_play == VLC_TRUE )            {                 playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,                                   p_playlist->status.i_view,                                   p_playlist->status.p_item, NULL );            }            vlc_object_release( p_playlist );        }        else        {            msg_Err( p_demux, "can't find playlist" );        }    }    if( !(p_mvhd = MP4_BoxGet( p_sys->p_root, "/moov/mvhd" ) ) )    {        if( !p_rmra )        {            msg_Err( p_demux, "cannot find /moov/mvhd" );            goto error;        }        else        {            msg_Warn( p_demux, "cannot find /moov/mvhd (pure ref file)" );            p_demux->pf_demux = DemuxRef;            return VLC_SUCCESS;        }    }    else    {        p_sys->i_timescale = p_mvhd->data.p_mvhd->i_timescale;        p_sys->i_duration = p_mvhd->data.p_mvhd->i_duration;    }    if( !( p_sys->i_tracks = MP4_BoxCount( p_sys->p_root, "/moov/trak" ) ) )    {        msg_Err( p_demux, "cannot find any /moov/trak" );        goto error;    }    msg_Dbg( p_demux, "find %d track%c",                        p_sys->i_tracks,                        p_sys->i_tracks ? 's':' ' );    /* allocate memory */    p_sys->track = calloc( p_sys->i_tracks, sizeof( mp4_track_t ) );    memset( p_sys->track, 0, p_sys->i_tracks * sizeof( mp4_track_t ) );    /* now process each track and extract all usefull information */    for( i = 0; i < p_sys->i_tracks; i++ )    {        p_trak = MP4_BoxGet( p_sys->p_root, "/moov/trak[%d]", i );        MP4_TrackCreate( p_demux, &p_sys->track[i], p_trak );        if( p_sys->track[i].b_ok )        {            char *psz_cat;            switch( p_sys->track[i].fmt.i_cat )            {                case( VIDEO_ES ):                    psz_cat = "video";                    break;                case( AUDIO_ES ):                    psz_cat = "audio";                    break;                case( SPU_ES ):                    psz_cat = "subtitle";                    break;                default:                    psz_cat = "unknown";                    break;            }            msg_Dbg( p_demux, "adding track[Id 0x%x] %s (%s) language %s",                     p_sys->track[i].i_track_ID, psz_cat,                     p_sys->track[i].b_enable ? "enable":"disable",                     p_sys->track[i].fmt.psz_language ?                     p_sys->track[i].fmt.psz_language : "undef" );        }        else        {            msg_Dbg( p_demux, "ignoring track[Id 0x%x]",                     p_sys->track[i].i_track_ID );        }    }    return VLC_SUCCESS;error:    if( p_sys->p_root )    {        MP4_BoxFree( p_demux->s, p_sys->p_root );    }    free( p_sys );    return VLC_EGENERIC;}/***************************************************************************** * Demux: read packet and send them to decoders ***************************************************************************** * TODO check for newly selected track (ie audio upt to now ) *****************************************************************************/static int Demux( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    unsigned int i_track;    unsigned int i_track_selected;    /* check for newly selected/unselected track */    for( i_track = 0, i_track_selected = 0; i_track < p_sys->i_tracks;         i_track++ )    {        mp4_track_t *tk = &p_sys->track[i_track];        vlc_bool_t b;        if( !tk->b_ok ||            ( tk->b_selected && tk->i_sample >= tk->i_sample_count ) )        {            continue;        }        es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );        if( tk->b_selected && !b )        {            MP4_TrackUnselect( p_demux, tk );        }        else if( !tk->b_selected && b)        {            MP4_TrackSelect( p_demux, tk, MP4_GetMoviePTS( p_sys ) );        }        if( tk->b_selected )        {            i_track_selected++;        }    }    if( i_track_selected <= 0 )    {        p_sys->i_time += __MAX( p_sys->i_timescale / 10 , 1 );        if( p_sys->i_timescale > 0 )        {            int64_t i_length = (mtime_t)1000000 *                               (mtime_t)p_sys->i_duration /                               (mtime_t)p_sys->i_timescale;            if( MP4_GetMoviePTS( p_sys ) >= i_length )                return 0;            return 1;        }        msg_Warn( p_demux, "no track selected, exiting..." );        return 0;    }    /* first wait for the good time to read a packet */    es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr + 1 );    p_sys->i_pcr = MP4_GetMoviePTS( p_sys );    /* we will read 100ms for each stream so ...*/    p_sys->i_time += __MAX( p_sys->i_timescale / 10 , 1 );    for( i_track = 0; i_track < p_sys->i_tracks; i_track++ )    {        mp4_track_t *tk = &p_sys->track[i_track];        if( !tk->b_ok || !tk->b_selected || tk->i_sample >= tk->i_sample_count )        {            continue;        }        while( MP4_TrackGetDTS( p_demux, tk ) < MP4_GetMoviePTS( p_sys ) )        {#if 0            msg_Dbg( p_demux, "tk(%i)=%lld mv=%lld", i_track,                     MP4_TrackGetDTS( p_demux, tk ),                     MP4_GetMoviePTS( p_sys ) );#endif            if( MP4_TrackSampleSize( tk ) > 0 )            {                block_t *p_block;                int64_t i_delta;                /* go,go go ! */                if( stream_Seek( p_demux->s, MP4_TrackGetPos( tk ) ) )                {                    msg_Warn( p_demux, "track[0x%x] will be disabled (eof?)",                              tk->i_track_ID );                    MP4_TrackUnselect( p_demux, tk );                    break;                }                /* now read pes */                if( !(p_block =                         stream_Block( p_demux->s, MP4_TrackSampleSize(tk) )) )                {                    msg_Warn( p_demux, "track[0x%x] will be disabled (eof?)",                              tk->i_track_ID );                    MP4_TrackUnselect( p_demux, tk );                    break;                }                if( tk->b_drms && tk->p_drms )                {                    drms_decrypt( tk->p_drms, (uint32_t*)p_block->p_buffer,                                  p_block->i_buffer );                }                else if( tk->fmt.i_cat == SPU_ES )                {                    if( tk->fmt.i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) &&                        p_block->i_buffer >= 2 )                    {                        uint16_t i_size = GetWBE( p_block->p_buffer );                        if( i_size + 2 <= p_block->i_buffer )                        {                            char *p;                            /* remove the length field, and append a '\0' */                            memmove( &p_block->p_buffer[0],                                     &p_block->p_buffer[2], i_size );                            p_block->p_buffer[i_size] = '\0';                            p_block->i_buffer = i_size + 1;                            /* convert \r -> \n */                            while( ( p = strchr( (char*)p_block->p_buffer, '\r' ) ) )                            {                                *p = '\n';                            }                        }                        else                        {                            /* Invalid */                            p_block->i_buffer = 0;                        }                    }                }                /* dts */                p_block->i_dts = MP4_TrackGetDTS( p_demux, tk ) + 1;                /* pts */                i_delta = MP4_TrackGetPTSDelta( p_demux, tk );                if( i_delta != -1 )                    p_block->i_pts = p_block->i_dts + i_delta;                else if( tk->fmt.i_cat != VIDEO_ES )                    p_block->i_pts = p_block->i_dts;                else                    p_block->i_pts = 0;                if( !tk->b_drms || ( tk->b_drms && tk->p_drms ) )                    es_out_Send( p_demux->out, tk->p_es, p_block );            }            /* Next sample */            if( MP4_TrackNextSample( p_demux, tk ) )            {                break;            }        }    }    return 1;}/***************************************************************************** * Seek: Got to i_date******************************************************************************/static int Seek( demux_t *p_demux, mtime_t i_date ){    demux_sys_t *p_sys = p_demux->p_sys;    unsigned int i_track;    /* First update update global time */    p_sys->i_time = i_date * p_sys->i_timescale / 1000000;    p_sys->i_pcr  = i_date;    /* Now for each stream try to go to this time */    for( i_track = 0; i_track < p_sys->i_tracks; i_track++ )    {        mp4_track_t *tk = &p_sys->track[i_track];        MP4_TrackSeek( p_demux, tk, i_date );    }    return VLC_SUCCESS;}/***************************************************************************** * Control: *****************************************************************************/static int Control( demux_t *p_demux, int i_query, va_list args ){    demux_sys_t *p_sys = p_demux->p_sys;    double f, *pf;    int64_t i64, *pi64;    switch( i_query )    {        case DEMUX_GET_POSITION:            pf = (double*)va_arg( args, double * );            if( p_sys->i_duration > 0 )            {                *pf = (double)p_sys->i_time / (double)p_sys->i_duration;            }            else            {                *pf = 0.0;            }            return VLC_SUCCESS;        case DEMUX_SET_POSITION:            f = (double)va_arg( args, double );            if( p_sys->i_timescale > 0 )            {                i64 = (int64_t)( f * (double)1000000 *                                 (double)p_sys->i_duration /                                 (double)p_sys->i_timescale );                return Seek( p_demux, i64 );            }            else return VLC_SUCCESS;        case DEMUX_GET_TIME:            pi64 = (int64_t*)va_arg( args, int64_t * );            if( p_sys->i_timescale > 0 )            {                *pi64 = (mtime_t)1000000 *                        (mtime_t)p_sys->i_time /                        (mtime_t)p_sys->i_timescale;            }            else *pi64 = 0;            return VLC_SUCCESS;        case DEMUX_SET_TIME:            i64 = (int64_t)va_arg( args, int64_t );            return Seek( p_demux, i64 );        case DEMUX_GET_LENGTH:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -