Changeset 36bde12633aa3997e24a121db8cf1fb56f936f96

Show
Ignore:
Timestamp:
24/05/08 00:49:22 (6 months ago)
Author:
Jean-Baptiste Kempf <jb@videolan.org>
git-committer:
Jean-Baptiste Kempf <jb@videolan.org> 1211582962 -0700
git-parent:

[93d9a388cab3b40a5361df3b779cbc5ff6e25140]

git-author:
Wang Bo <silencewang@msn.com> 1211546306 +0800
Message:

real file index and seek

Signed-off-by: Jean-Baptiste Kempf <jb@ambre.(none)>

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/demux/real.c

    r13ae40b r36bde12  
    9696    int         i_subpackets; 
    9797    block_t     **p_subpackets; 
     98    int64_t        *p_subpackets_timecode; 
    9899    int         i_out_subpacket; 
    99100 
    100101} real_track_t; 
     102 
     103typedef struct 
     104{ 
     105    uint32_t file_offset; 
     106    uint32_t time_offset; 
     107    uint32_t frame_index; 
     108} rm_index_t; 
    101109 
    102110struct demux_sys_t 
     
    122130 
    123131    int64_t     i_pcr; 
     132    vlc_meta_t *p_meta; 
     133 
     134    int64_t i_index_offset; 
     135    int        b_seek; 
     136    rm_index_t * p_index; 
    124137}; 
    125138 
     
    164177    p_sys->i_pcr   = 1; 
    165178 
     179    p_sys->b_seek  = 0; 
    166180 
    167181    /* Parse the headers */ 
     
    213227                block_Release( tk->p_subpackets[ j ] ); 
    214228        } 
    215         if( tk->i_subpackets ) free( tk->p_subpackets ); 
     229        if( tk->i_subpackets ) 
     230        { 
     231            free( tk->p_subpackets ); 
     232            free( tk->p_subpackets_timecode ); 
     233        } 
    216234 
    217235        free( tk ); 
     
    222240    free( p_sys->psz_copyright ); 
    223241    free( p_sys->psz_description ); 
     242    free( p_sys->p_index ); 
    224243 
    225244    if( p_sys->i_track > 0 ) free( p_sys->track ); 
     
    517536 
    518537            /* Sanity check */ 
    519             if( i_flags & 2 ) y = tk->i_subpacket = 0; 
     538            if( i_flags & 2 || ( p_sys->b_seek ) ) 
     539            { 
     540                y = tk->i_subpacket = 0; 
     541                tk->i_out_subpacket = 0; 
     542                p_sys->b_seek = 0; 
     543            } 
    520544 
    521545            if( tk->fmt.i_codec == VLC_FOURCC( 'c', 'o', 'o', 'k' ) || 
    522546                tk->fmt.i_codec == VLC_FOURCC( 'a', 't', 'r', 'c' )) 
    523             for( i = 0; i < tk->i_frame_size / tk->i_subpacket_size; i++ ) 
    524             { 
    525                 block_t *p_block = block_New( p_demux, tk->i_subpacket_size ); 
    526                 memcpy( p_block->p_buffer, p_buf, tk->i_subpacket_size ); 
    527                 p_buf += tk->i_subpacket_size; 
    528  
    529                 i_index = tk->i_subpacket_h * i + 
    530                     ((tk->i_subpacket_h + 1) / 2) * (y&1) + (y>>1); 
     547            { 
     548                int num = tk->i_frame_size / tk->i_subpacket_size; 
     549                for( i = 0; i <  num; i++ ) 
     550                { 
     551                    block_t *p_block = block_New( p_demux, tk->i_subpacket_size ); 
     552                    memcpy( p_block->p_buffer, p_buf, tk->i_subpacket_size ); 
     553                    p_buf += tk->i_subpacket_size; 
     554 
     555                    i_index = tk->i_subpacket_h * i + 
     556                        ((tk->i_subpacket_h + 1) / 2) * (y&1) + (y>>1); 
     557 
     558                    if ( tk->p_subpackets[i_index]  != NULL ) 
     559                    { 
     560                        msg_Dbg(p_demux, "p_subpackets[ %d ] not null!",  i_index ); 
     561                        free( tk->p_subpackets[i_index] ); 
     562                    } 
     563 
     564                    tk->p_subpackets[i_index] = p_block; 
     565                    tk->i_subpacket++; 
     566                    p_block->i_dts = p_block->i_pts = 0; 
     567                } 
     568                tk->p_subpackets_timecode[tk->i_subpacket - num] = i_pts; 
     569            } 
     570 
     571            if( tk->fmt.i_codec == VLC_FOURCC( '2', '8', '_', '8' ) || 
     572                tk->fmt.i_codec == VLC_FOURCC( 's', 'i', 'p', 'r' ) ) 
     573            for( i = 0; i < tk->i_subpacket_h / 2; i++ ) 
     574            { 
     575                block_t *p_block = block_New( p_demux, tk->i_coded_frame_size); 
     576                memcpy( p_block->p_buffer, p_buf, tk->i_coded_frame_size ); 
     577                p_buf += tk->i_coded_frame_size; 
     578 
     579                i_index = (i * 2 * tk->i_frame_size) / 
     580                    tk->i_coded_frame_size + y; 
    531581 
    532582                p_block->i_dts = p_block->i_pts = i_pts; 
     
    535585            } 
    536586 
    537             if( tk->fmt.i_codec == VLC_FOURCC( '2', '8', '_', '8' ) || 
    538                 tk->fmt.i_codec == VLC_FOURCC( 's', 'i', 'p', 'r' ) ) 
    539             for( i = 0; i < tk->i_subpacket_h / 2; i++ ) 
    540             { 
    541                 block_t *p_block = block_New( p_demux, tk->i_coded_frame_size); 
    542                 memcpy( p_block->p_buffer, p_buf, tk->i_coded_frame_size ); 
    543                 p_buf += tk->i_coded_frame_size; 
    544  
    545                 i_index = (i * 2 * tk->i_frame_size) / 
    546                     tk->i_coded_frame_size + y; 
    547  
    548                 p_block->i_dts = p_block->i_pts = i_pts; 
    549                 tk->p_subpackets[i_index] = p_block; 
    550                 tk->i_subpacket++; 
    551             } 
    552  
    553587            while( tk->i_out_subpacket != tk->i_subpackets && 
    554588                   tk->p_subpackets[tk->i_out_subpacket] ) 
    555589            { 
    556590                /* Set the PCR */ 
     591#if 0 
    557592                if (tk->i_out_subpacket == 0) 
    558593                { 
     
    566601 
    567602                if( tk->i_out_subpacket ) p_block->i_dts = p_block->i_pts = 0; 
     603#endif 
     604 
     605                block_t *p_block = tk->p_subpackets[tk->i_out_subpacket]; 
     606                tk->p_subpackets[tk->i_out_subpacket] = 0; 
     607                //if ( p_block->i_dts ) 
     608                if ( tk->p_subpackets_timecode[tk->i_out_subpacket]  ) 
     609                { 
     610                    p_block->i_dts = p_block->i_pts = 
     611                        tk->p_subpackets_timecode[tk->i_out_subpacket]; 
     612                    tk->p_subpackets_timecode[tk->i_out_subpacket] = 0; 
     613 
     614                    p_sys->i_pcr = p_block->i_dts; 
     615                    es_out_Control( p_demux->out, ES_OUT_SET_PCR, 
     616                            (int64_t)p_sys->i_pcr ); 
     617                } 
    568618                es_out_Send( p_demux->out, tk->p_es, p_block ); 
    569619 
     
    654704{ 
    655705    demux_sys_t *p_sys = p_demux->p_sys; 
    656 #if 0 
    657706    double f, *pf; 
    658707    int64_t i64; 
    659 #endif 
     708    rm_index_t * p_index; 
    660709    int64_t *pi64; 
    661710 
    662711    switch( i_query ) 
    663712    { 
    664 #if 0 
    665713        case DEMUX_GET_POSITION: 
    666714            pf = (double*) va_arg( args, double* ); 
     715 
     716            if( p_sys->i_our_duration > 0 ) 
     717            { 
     718                *pf = (double)p_sys->i_pcr / 1000.0 / p_sys->i_our_duration; 
     719                return VLC_SUCCESS; 
     720            } 
     721 
     722            /* read stream size maybe failed in rtsp streaming,  
     723               so use duration to determin the position at first  */ 
    667724            i64 = stream_Size( p_demux->s ); 
    668725            if( i64 > 0 ) 
    669726            { 
    670                 *pf = (double)stream_Tell( p_demux->s ) / (double)i64; 
     727                *pf = (double)1.0*stream_Tell( p_demux->s ) / (double)i64; 
    671728            } 
    672729            else 
     
    675732            } 
    676733            return VLC_SUCCESS; 
     734 
     735        case DEMUX_GET_TIME: 
     736            pi64 = (int64_t*)va_arg( args, int64_t * ); 
     737 
     738            if( p_sys->i_our_duration > 0 ) 
     739            { 
     740                *pi64 = p_sys->i_pcr; 
     741                return VLC_SUCCESS; 
     742            } 
     743 
     744            /* same as GET_POSTION */ 
     745            i64 = stream_Size( p_demux->s ); 
     746            if( p_sys->i_our_duration > 0 && i64 > 0 ) 
     747            { 
     748                *pi64 = (int64_t)( 1000.0 * p_sys->i_our_duration * stream_Tell( p_demux->s ) / i64 ); 
     749                return VLC_SUCCESS; 
     750            } 
     751 
     752            *pi64 = 0; 
     753            return VLC_EGENERIC; 
    677754 
    678755        case DEMUX_SET_POSITION: 
    679756            f = (double) va_arg( args, double ); 
    680             i64 = stream_Size( p_demux->s ); 
    681  
    682             es_out_Control( p_demux->out, ES_OUT_RESET_PCR ); 
    683  
    684             return stream_Seek( p_demux->s, (int64_t)(i64 * f) ); 
    685  
    686         case DEMUX_GET_TIME: 
    687             pi64 = (int64_t*)va_arg( args, int64_t * ); 
    688             if( p_sys->i_mux_rate > 0 ) 
    689             { 
    690                 *pi64 = (int64_t)1000000 * ( stream_Tell( p_demux->s ) / 50 ) / p_sys->i_mux_rate; 
    691                 return VLC_SUCCESS; 
    692             } 
    693             *pi64 = 0; 
    694             return VLC_EGENERIC; 
    695 #endif 
     757            i64 = (int64_t) ( stream_Size( p_demux->s ) * f ); 
     758 
     759            //msg_Dbg(p_demux,"Seek Real  DEMUX_SET_POSITION : %f file_offset :"I64Fd" p_sys->i_pcr "I64Fd" ", f, i64 , p_sys->i_pcr ); 
     760 
     761            if ( p_sys->i_index_offset == 0 && i64 != 0 ) 
     762            { 
     763                msg_Err(p_demux,"Seek No Index Real File failed!" ); 
     764                return VLC_EGENERIC; // no index! 
     765            } 
     766            if ( i64 == 0 ) 
     767            { 
     768                /* it is a rtsp stream , it is specials in access/rtsp/... */ 
     769 
     770                msg_Dbg(p_demux, "Seek in real rtsp stream!"); 
     771                p_sys->i_pcr = (int64_t)1000 * ( p_sys->i_our_duration * f  ); 
     772 
     773                es_out_Control( p_demux->out, ES_OUT_RESET_PCR , p_sys->i_pcr ); 
     774                p_sys->b_seek = 1; 
     775 
     776                return stream_Seek( p_demux->s, p_sys->i_pcr ); 
     777            } 
     778 
     779            if ( p_sys->i_index_offset > 0 ) 
     780            { 
     781                p_index = p_sys->p_index; 
     782                while( p_index->file_offset !=0 ) 
     783                { 
     784                    if ( p_index->file_offset > i64 ) 
     785                    { 
     786    /* 
     787                    msg_Dbg(p_demux, "Seek Real find! %d %d %d", p_index->time_offset, p_index->file_offset ,(uint32_t) i64); 
     788    */ 
     789                        if ( p_index != p_sys->p_index ) p_index --; 
     790                        i64 = p_index->file_offset; 
     791                        break; 
     792                    } 
     793                    p_index++; 
     794                } 
     795 
     796                //msg_Dbg(p_demux, "Seek Real pcr from :"I64Fd" to "I64Fd"  ", p_sys->i_pcr , 1000 * (int64_t) p_index->time_offset  ); 
     797                p_sys->i_pcr = 1000 * (int64_t) p_index->time_offset; 
     798 
     799                es_out_Control( p_demux->out, ES_OUT_RESET_PCR , p_sys->i_pcr ); 
     800 
     801                return stream_Seek( p_demux->s, i64 ); 
     802            } 
     803        case DEMUX_SET_TIME: 
     804            i64 = (int64_t) va_arg( args, int64_t ) / 1000; 
     805            //msg_Dbg(p_demux,"DEMUX_SET_TIME :OK  "I64Fd" ",i64); 
     806 
     807            p_index = p_sys->p_index; 
     808            while( p_index->file_offset !=0 ) 
     809            { 
     810                if ( p_index->time_offset > i64 ) 
     811                { 
     812                    if ( p_index != p_sys->p_index ) 
     813                        p_index --; 
     814                    i64 = p_index->file_offset; 
     815                    break; 
     816                } 
     817                p_index++; 
     818            } 
     819 
     820            p_sys->i_pcr = 1000 * (int64_t) p_index->time_offset; 
     821            es_out_Control( p_demux->out, ES_OUT_RESET_PCR , p_sys->i_pcr ); 
     822 
     823            return stream_Seek( p_demux->s, i64 ); 
    696824 
    697825        case DEMUX_GET_LENGTH: 
     
    732860        } 
    733861 
    734         case DEMUX_SET_TIME: 
    735862        case DEMUX_GET_FPS: 
    736863        default: 
     
    738865    } 
    739866    return VLC_EGENERIC; 
     867} 
     868 
     869/***************************************************************************** 
     870 * ReadRealIndex: 
     871 *****************************************************************************/ 
     872 
     873static void ReadRealIndex( demux_t *p_demux ) 
     874{ 
     875    demux_sys_t *p_sys = p_demux->p_sys; 
     876    uint8_t buffer[100]; 
     877    uint32_t    i_id; 
     878    uint32_t    i_size; 
     879    int         i_version; 
     880    int            i; 
     881 
     882    uint32_t    i_index_count; 
     883 
     884    if ( p_sys->i_index_offset == 0 ) 
     885        return; 
     886 
     887    stream_Seek( p_demux->s, p_sys->i_index_offset ); 
     888 
     889    if ( stream_Read( p_demux->s, buffer, 20 ) < 20 ) 
     890        return ; 
     891 
     892    i_id = VLC_FOURCC( buffer[0], buffer[1], buffer[2], buffer[3] ); 
     893    i_size      = GetDWBE( &buffer[4] ); 
     894    i_version   = GetWBE( &buffer[8] ); 
     895 
     896    msg_Dbg( p_demux, "Real index %4.4s size=%d version=%d", 
     897                 (char*)&i_id, i_size, i_version ); 
     898 
     899    if( (i_size < 20) && (i_id != VLC_FOURCC('I','N','D','X')) ) 
     900        return; 
     901 
     902    i_index_count = GetDWBE( &buffer[10] ); 
     903 
     904    msg_Dbg( p_demux, "Real Index : num : %d ", i_index_count ); 
     905 
     906    if ( i_index_count == 0 ) 
     907        return; 
     908 
     909    if (  GetDWBE( &buffer[16] ) > 0 ) 
     910        msg_Dbg( p_demux, "Real Index: next index is exist? %d ", GetDWBE( &buffer[16] )  ); 
     911 
     912    p_sys->p_index =  ( rm_index_t *) malloc( sizeof(rm_index_t) * (i_index_count+1) ); 
     913    if ( p_sys->p_index == NULL ) 
     914    { 
     915        msg_Err( p_demux, "Real Index: Error , fail to malloc index buffer " ); 
     916        return; 
     917    } 
     918 
     919    memset( p_sys->p_index, 0, sizeof(rm_index_t) * (i_index_count+1) ); 
     920 
     921    for( i=0; i<i_index_count; i++ ) 
     922    { 
     923        if ( stream_Read( p_demux->s, buffer, 14 ) < 14 ) 
     924            return ; 
     925 
     926        if ( GetWBE( &buffer[0] ) != 0 ) 
     927        { 
     928            msg_Dbg( p_demux, "Real Index: invaild version of index entry %d ", GetWBE( &buffer[0] ) ); 
     929            return; 
     930        } 
     931 
     932        p_sys->p_index[i].time_offset = GetDWBE( &buffer[2] ); 
     933        p_sys->p_index[i].file_offset = GetDWBE( &buffer[6] ); 
     934        p_sys->p_index[i].frame_index = GetDWBE( &buffer[10] ); 
     935#if 0 
     936        msg_Dbg( p_demux, "Real Index: time %d file %d frame %d ", p_sys->p_index[i].time_offset, p_sys->p_index[i].file_offset , p_sys->p_index[i].frame_index ); 
     937#endif 
     938 
     939    } 
     940 
    740941} 
    741942 
     
    752953    int64_t     i_skip; 
    753954    int         i_version; 
     955    p_sys->p_meta = vlc_meta_New(); 
    754956 
    755957    for( ;; ) 
     
    8021004            p_sys->i_our_duration = (int)GetDWBE(&header[20]); 
    8031005  
     1006            p_sys->i_index_offset = GetDWBE(&header[28]); 
     1007 
    8041008            i_flags = GetWBE(&header[38]); 
    8051009            msg_Dbg( p_demux, "    - flags=0x%x %s%s%s", 
     
    8281032                msg_Dbg( p_demux, "    - title=`%s'", psz ); 
    8291033                p_sys->psz_title = psz; 
     1034                vlc_meta_Add( p_sys->p_meta, VLC_META_TITLE, psz ); 
     1035                free( psz ); 
    8301036                i_skip -= i_len; 
    8311037            } 
     
    8421048                msg_Dbg( p_demux, "    - author=`%s'", psz ); 
    8431049                p_sys->psz_artist = psz; 
     1050                vlc_meta_Add( p_sys->p_meta, VLC_META_ARTIST, psz ); 
     1051                free( psz ); 
    8441052                i_skip -= i_len; 
    8451053            } 
     
    8561064                msg_Dbg( p_demux, "    - copyright=`%s'", psz ); 
    8571065                p_sys->psz_copyright = psz; 
     1066                vlc_meta_Add( p_sys->p_meta, VLC_META_COPYRIGHT, psz ); 
     1067                free( psz ); 
    8581068                i_skip -= i_len; 
    8591069            } 
     
    8701080                msg_Dbg( p_demux, "    - comment=`%s'", psz ); 
    8711081                p_sys->psz_description = psz; 
     1082                vlc_meta_Add( p_sys->p_meta, VLC_META_DESCRIPTION, psz ); 
     1083                free( psz ); 
    8721084                i_skip -= i_len; 
    8731085            } 
     
    9591171    /* TODO read index if possible */ 
    9601172 
     1173    if ( p_sys->i_index_offset > 0 ) 
     1174    { 
     1175        int64_t pos; 
     1176        pos = stream_Tell( p_demux->s ); 
     1177        ReadRealIndex( p_demux ); 
     1178        stream_Seek( p_demux->s, pos ); 
     1179    } 
     1180 
    9611181    return VLC_SUCCESS; 
    9621182} 
     
    10151235        tk->i_subpackets = 0; 
    10161236        tk->p_subpackets = NULL; 
     1237        tk->p_subpackets_timecode = NULL; 
    10171238        tk->i_id = i_num; 
    10181239        tk->fmt = fmt; 
     
    10251246    else if( !strncmp( (char *)p_peek, ".ra\xfd", 4 ) ) 
    10261247    { 
    1027         int i_header_size, i_flavor, i_coded_frame_size, i_subpacket_h; 
    1028         int i_frame_size, i_subpacket_size; 
     1248        int i_header_size = 0; 
     1249        int i_flavor = 0; 
     1250        int i_coded_frame_size = 0; 
     1251        int i_subpacket_h = 0; 
     1252        int i_frame_size = 0; 
     1253        int i_subpacket_size = 0; 
    10291254        char p_genr[4]; 
    10301255        int i_version = GetWBE( &p_peek[4] );   /* [0..3] = '.','r','a',0xfd */ 
     
    12471472            tk->i_subpackets = 0; 
    12481473            tk->p_subpackets = NULL; 
     1474            tk->p_subpackets_timecode = NULL; 
    12491475            if( fmt.i_codec == VLC_FOURCC('c','o','o','k') 
    12501476             || fmt.i_codec == VLC_FOURCC('a','t','r','c') ) 
     
    12541480                tk->p_subpackets = 
    12551481                    calloc( tk->i_subpackets, sizeof(block_t *) ); 
     1482                tk->p_subpackets_timecode = 
     1483                    calloc( tk->i_subpackets , sizeof( int64_t ) ); 
    12561484            } 
    12571485            else if( fmt.i_codec == VLC_FOURCC('2','8','_','8') ) 
     
    12611489                tk->p_subpackets = 
    12621490                    calloc( tk->i_subpackets, sizeof(block_t *) ); 
     1491                tk->p_subpackets_timecode = 
     1492                    calloc( tk->i_subpackets , sizeof( int64_t ) ); 
    12631493            } 
    12641494