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

📄 mp4.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
        {            MP4_Box_t *p_rdrf = MP4_BoxGet( p_rmra, "rmda[%d]/rdrf", i );            char      *psz_ref;            uint32_t  i_ref_type;            if( !p_rdrf || !( psz_ref = strdup( p_rdrf->data.p_rdrf->psz_ref ) ) )            {                continue;            }            i_ref_type = p_rdrf->data.p_rdrf->i_ref_type;            msg_Dbg( p_demux, "new ref=`%s' type=%4.4s",                     psz_ref, (char*)&i_ref_type );            if( i_ref_type == VLC_FOURCC( 'u', 'r', 'l', ' ' ) )            {                if( strstr( psz_ref, "qt5gateQT" ) )                {                    msg_Dbg( p_demux, "ignoring pseudo ref =`%s'", psz_ref );                    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';                    if( asprintf( &psz_absolute, "%s://%s%s",                                  p_demux->psz_access, psz_path, psz_ref ) < 0 )                        return VLC_ENOMEM;                    free( psz_ref );                    psz_ref = psz_absolute;                    free( psz_path );                }                input_item_t *p_input;                msg_Dbg( p_demux, "adding ref = `%s'", psz_ref );                p_input = input_item_NewExt( p_demux, psz_ref, NULL,                                    0, NULL, -1 );                input_item_CopyOptions( p_current, p_input );                input_item_AddSubItem( p_current, p_input );                vlc_gc_decref( p_input );            }            else            {                msg_Err( p_demux, "unknown ref type=%4.4s FIXME (send a bug report)",                         (char*)&p_rdrf->data.p_rdrf->i_ref_type );            }            free( psz_ref );        }        vlc_object_release( p_input );    }    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;        if( p_sys->i_timescale == 0 )        {            msg_Err( p_this, "bad timescale" );            goto error;        }        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, "found %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 ) );    if( p_sys->track == NULL )        goto error;    memset( p_sys->track, 0, p_sys->i_tracks * sizeof( mp4_track_t ) );    /* Search the first chap reference (like quicktime) and     * check that at least 1 stream is enabled */    p_sys->p_tref_chap = NULL;    b_enabled_es = false;    for( i = 0; i < p_sys->i_tracks; i++ )    {        MP4_Box_t *p_trak = MP4_BoxGet( p_sys->p_root, "/moov/trak[%d]", i );        MP4_Box_t *p_tkhd = MP4_BoxGet( p_trak, "tkhd" );        if( p_tkhd && (p_tkhd->data.p_tkhd->i_flags&MP4_TRACK_ENABLED) )            b_enabled_es = true;        MP4_Box_t *p_chap = MP4_BoxGet( p_trak, "tref/chap", i );        if( p_chap && p_chap->data.p_tref_generic->i_entry_count > 0 && !p_sys->p_tref_chap )            p_sys->p_tref_chap = p_chap;    }    /* 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, !b_enabled_es );        if( p_sys->track[i].b_ok && !p_sys->track[i].b_chapter )        {            const 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 if( p_sys->track[i].b_ok && p_sys->track[i].b_chapter )        {            msg_Dbg( p_demux, "using track[Id 0x%x] for chapter language %s",                     p_sys->track[i].i_track_ID,                     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 );        }    }    /* */    LoadChapter( p_demux );    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];        bool b;        if( !tk->b_ok || tk->b_chapter ||            ( 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;    }    /* */    MP4_UpdateSeekpoint( p_demux );    /* 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_chapter || !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( 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;}static void MP4_UpdateSeekpoint( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    int64_t i_time;    int i;    if( !p_sys->p_title )        return;    i_time = MP4_GetMoviePTS( p_sys );    for( i = 0; i < p_sys->p_title->i_seekpoint; i++ )    {        if( i_time < p_sys->p_title->seekpoint[i]->i_time_offset )            break;    }    i--;    if( i != p_demux->info.i_seekpoint && i >= 0 )    {        p_demux->info.i_seekpoint = i;        p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;    }}/***************************************************************************** * 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;

⌨️ 快捷键说明

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