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

📄 mp4.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
static bo_t *GetTextBox( sout_mux_t *p_mux, mp4_stream_t *p_stream ){    bo_t *text = box_new( "text" );    int  i;    for( i = 0; i < 6; i++ )    {        bo_add_8( text, 0 );        // reserved;    }    bo_add_16be( text, 1 );         // data-reference-index    bo_add_32be( text, 0 );         // display flags    bo_add_32be( text, 0 );         // justification    for( i = 0; i < 3; i++ )    {        bo_add_16be( text, 0 );     // back ground color    }    bo_add_16be( text, 0 );         // box text    bo_add_16be( text, 0 );         // box text    bo_add_16be( text, 0 );         // box text    bo_add_16be( text, 0 );         // box text    bo_add_64be( text, 0 );         // reserved    for( i = 0; i < 3; i++ )    {        bo_add_16be( text, 0xff );  // foreground color    }    bo_add_8 ( text, 9 );    bo_add_mem( text, 9, (uint8_t*)"Helvetica" );    box_fix( text );    return text;}static bo_t *GetStblBox( sout_mux_t *p_mux, mp4_stream_t *p_stream ){    sout_mux_sys_t *p_sys = p_mux->p_sys;    unsigned int i_chunk, i_stsc_last_val, i_stsc_entries, i, i_index;    bo_t *stbl, *stsd, *stts, *stco, *stsc, *stsz, *stss;    uint32_t i_timescale;    int64_t i_dts, i_dts_q;    stbl = box_new( "stbl" );    /* sample description */    stsd = box_full_new( "stsd", 0, 0 );    bo_add_32be( stsd, 1 );    if( p_stream->fmt.i_cat == AUDIO_ES )    {        bo_t *soun = GetSounBox( p_mux, p_stream );        box_gather( stsd, soun );    }    else if( p_stream->fmt.i_cat == VIDEO_ES )    {        bo_t *vide = GetVideBox( p_mux, p_stream );        box_gather( stsd, vide );    }    else if( p_stream->fmt.i_cat == SPU_ES )    {        box_gather( stsd, GetTextBox( p_mux, p_stream ) );    }    box_fix( stsd );    /* chunk offset table */    if( p_sys->i_pos >= (((uint64_t)0x1) << 32) )    {        /* 64 bits version */        p_stream->b_stco64 = VLC_TRUE;        stco = box_full_new( "co64", 0, 0 );    }    else    {        /* 32 bits version */        p_stream->b_stco64 = VLC_FALSE;        stco = box_full_new( "stco", 0, 0 );    }    bo_add_32be( stco, 0 );     // entry-count (fixed latter)    /* sample to chunk table */    stsc = box_full_new( "stsc", 0, 0 );    bo_add_32be( stsc, 0 );     // entry-count (fixed latter)    for( i_chunk = 0, i_stsc_last_val = 0, i_stsc_entries = 0, i = 0;         i < p_stream->i_entry_count; i_chunk++ )    {        int i_first = i;        if( p_stream->b_stco64 )            bo_add_64be( stco, p_stream->entry[i].i_pos );        else            bo_add_32be( stco, p_stream->entry[i].i_pos );        while( i < p_stream->i_entry_count )        {            if( i + 1 < p_stream->i_entry_count &&                p_stream->entry[i].i_pos + p_stream->entry[i].i_size                != p_stream->entry[i + 1].i_pos )            {                i++;                break;            }            i++;        }        /* Add entry to the stsc table */        if( i_stsc_last_val != i - i_first )        {            bo_add_32be( stsc, 1 + i_chunk );   // first-chunk            bo_add_32be( stsc, i - i_first ) ;  // samples-per-chunk            bo_add_32be( stsc, 1 );             // sample-descr-index            i_stsc_last_val = i - i_first;            i_stsc_entries++;        }    }    /* Fix stco entry count */    bo_fix_32be( stco, 12, i_chunk );    msg_Dbg( p_mux, "created %d chunks (stco)", i_chunk );    box_fix( stco );    /* Fix stsc entry count */    bo_fix_32be( stsc, 12, i_stsc_entries  );    box_fix( stsc );    /* add stts */    stts = box_full_new( "stts", 0, 0 );    bo_add_32be( stts, 0 );     // entry-count (fixed latter)    if( p_stream->fmt.i_cat == AUDIO_ES )        i_timescale = p_stream->fmt.audio.i_rate;    else        i_timescale = 1001;    /* first, create quantified length */    for( i = 0, i_dts = 0, i_dts_q = 0; i < p_stream->i_entry_count; i++ )    {        int64_t i_dts_deq = i_dts_q * I64C(1000000) / (int64_t)i_timescale;        int64_t i_delta = p_stream->entry[i].i_length + i_dts - i_dts_deq;        i_dts += p_stream->entry[i].i_length;        p_stream->entry[i].i_length =            i_delta * (int64_t)i_timescale / I64C(1000000);        i_dts_q += p_stream->entry[i].i_length;    }    /* then write encoded table */    for( i = 0, i_index = 0; i < p_stream->i_entry_count; i_index++)    {        int     i_first = i;        int64_t i_delta = p_stream->entry[i].i_length;        while( i < p_stream->i_entry_count )        {            i++;            if( i >= p_stream->i_entry_count ||                p_stream->entry[i].i_length != i_delta )            {                break;            }        }        bo_add_32be( stts, i - i_first ); // sample-count        bo_add_32be( stts, i_delta );     // sample-delta    }    bo_fix_32be( stts, 12, i_index );    box_fix( stts );    /* FIXME add ctts ?? FIXME */    stsz = box_full_new( "stsz", 0, 0 );    bo_add_32be( stsz, 0 );                             // sample-size    bo_add_32be( stsz, p_stream->i_entry_count );       // sample-count    for( i = 0; i < p_stream->i_entry_count; i++ )    {        bo_add_32be( stsz, p_stream->entry[i].i_size ); // sample-size    }    box_fix( stsz );    /* create stss table */    stss = NULL;    for( i = 0, i_index = 0; i < p_stream->i_entry_count; i++ )    {        if( p_stream->entry[i].i_flags & BLOCK_FLAG_TYPE_I )        {            if( stss == NULL )            {                stss = box_full_new( "stss", 0, 0 );                bo_add_32be( stss, 0 ); /* fixed later */            }            bo_add_32be( stss, 1 + i );            i_index++;        }    }    if( stss )    {        bo_fix_32be( stss, 12, i_index );        box_fix( stss );    }    /* Now gather all boxes into stbl */    box_gather( stbl, stsd );    box_gather( stbl, stts );    if( stss )    {        box_gather( stbl, stss );    }    box_gather( stbl, stsc );    box_gather( stbl, stsz );    p_stream->i_stco_pos = stbl->i_buffer + 16;    box_gather( stbl, stco );    /* finish stbl */    box_fix( stbl );    return stbl;}static int64_t get_timestamp();static uint32_t mvhd_matrix[9] =    { 0x10000, 0, 0, 0, 0x10000, 0, 0, 0, 0x40000000 };static bo_t *GetMoovBox( sout_mux_t *p_mux ){    sout_mux_sys_t *p_sys = p_mux->p_sys;    bo_t            *moov, *mvhd;    int             i_trak, i;    uint32_t        i_movie_timescale = 90000;    int64_t         i_movie_duration  = 0;    moov = box_new( "moov" );    /* Create general info */    for( i_trak = 0; i_trak < p_sys->i_nb_streams; i_trak++ )    {        mp4_stream_t *p_stream = p_sys->pp_streams[i_trak];        i_movie_duration = __MAX( i_movie_duration, p_stream->i_duration );    }    msg_Dbg( p_mux, "movie duration %ds",             (uint32_t)( i_movie_duration / (mtime_t)1000000 ) );    i_movie_duration = i_movie_duration * i_movie_timescale / 1000000;    /* *** add /moov/mvhd *** */    if( !p_sys->b_64_ext )    {        mvhd = box_full_new( "mvhd", 0, 0 );        bo_add_32be( mvhd, get_timestamp() );   // creation time        bo_add_32be( mvhd, get_timestamp() );   // modification time        bo_add_32be( mvhd, i_movie_timescale);  // timescale        bo_add_32be( mvhd, i_movie_duration );  // duration    }    else    {        mvhd = box_full_new( "mvhd", 1, 0 );        bo_add_64be( mvhd, get_timestamp() );   // creation time        bo_add_64be( mvhd, get_timestamp() );   // modification time        bo_add_32be( mvhd, i_movie_timescale);  // timescale        bo_add_64be( mvhd, i_movie_duration );  // duration    }    bo_add_32be( mvhd, 0x10000 );           // rate    bo_add_16be( mvhd, 0x100 );             // volume    bo_add_16be( mvhd, 0 );                 // reserved    for( i = 0; i < 2; i++ )    {        bo_add_32be( mvhd, 0 );             // reserved    }    for( i = 0; i < 9; i++ )    {        bo_add_32be( mvhd, mvhd_matrix[i] );// matrix    }    for( i = 0; i < 6; i++ )    {        bo_add_32be( mvhd, 0 );             // pre-defined    }    /* Next available track id */    bo_add_32be( mvhd, p_sys->i_nb_streams + 1 ); // next-track-id    box_fix( mvhd );    box_gather( moov, mvhd );    for( i_trak = 0; i_trak < p_sys->i_nb_streams; i_trak++ )    {        mp4_stream_t *p_stream;        uint32_t     i_timescale;        bo_t *trak, *tkhd, *edts, *elst, *mdia, *mdhd, *hdlr;        bo_t *minf, *dinf, *dref, *url, *stbl;        p_stream = p_sys->pp_streams[i_trak];        if( p_stream->fmt.i_cat == AUDIO_ES )            i_timescale = p_stream->fmt.audio.i_rate;        else            i_timescale = 1001;        /* *** add /moov/trak *** */        trak = box_new( "trak" );        /* *** add /moov/trak/tkhd *** */        if( !p_sys->b_64_ext )        {            if( p_sys->b_mov )                tkhd = box_full_new( "tkhd", 0, 0x0f );            else                tkhd = box_full_new( "tkhd", 0, 1 );            bo_add_32be( tkhd, get_timestamp() );       // creation time            bo_add_32be( tkhd, get_timestamp() );       // modification time            bo_add_32be( tkhd, p_stream->i_track_id );            bo_add_32be( tkhd, 0 );                     // reserved 0            bo_add_32be( tkhd, p_stream->i_duration *                         (int64_t)i_movie_timescale /                         (mtime_t)1000000 );            // duration        }        else        {            if( p_sys->b_mov )                tkhd = box_full_new( "tkhd", 1, 0x0f );            else                tkhd = box_full_new( "tkhd", 1, 1 );            bo_add_64be( tkhd, get_timestamp() );       // creation time            bo_add_64be( tkhd, get_timestamp() );       // modification time            bo_add_32be( tkhd, p_stream->i_track_id );            bo_add_32be( tkhd, 0 );                     // reserved 0            bo_add_64be( tkhd, p_stream->i_duration *                         (int64_t)i_movie_timescale /                         (mtime_t)1000000 );            // duration        }        for( i = 0; i < 2; i++ )        {            bo_add_32be( tkhd, 0 );                 // reserved        }        bo_add_16be( tkhd, 0 );                     // layer        bo_add_16be( tkhd, 0 );                     // pre-defined        // volume        bo_add_16be( tkhd, p_stream->fmt.i_cat == AUDIO_ES ? 0x100 : 0 );        bo_add_16be( tkhd, 0 );                     // reserved        for( i = 0; i < 9; i++ )        {            bo_add_32be( tkhd, mvhd_matrix[i] );    // matrix        }        if( p_stream->fmt.i_cat == AUDIO_ES )        {            bo_add_32be( tkhd, 0 );                 // width (presentation)            bo_add_32be( tkhd, 0 );                 // height(presentation)        }        else if( p_stream->fmt.i_cat == VIDEO_ES )        {            int i_width = p_stream->fmt.video.i_width << 16;            if( p_stream->fmt.video.i_aspect > 0 )            {                i_width = (int64_t)p_stream->fmt.video.i_aspect *                          ((int64_t)p_stream->fmt.video.i_height << 16) /                          VOUT_ASPECT_FACTOR;            }            // width (presentation)            bo_add_32be( tkhd, i_width );            // height(presentation)            bo_add_32be( tkhd, p_stream->fmt.video.i_height << 16 );        }        else        {            int i_width = 320 << 16;            int i_height = 200;            int i;            for( i = 0; i < p_sys->i_nb_streams; i++ )            {                mp4_stream_t *tk = p_sys->pp_streams[i];                if( tk->fmt.i_cat == VIDEO_ES )                {                    if( p_stream->fmt.video.i_aspect )                        i_width = (int64_t)p_stream->fmt.video.i_aspect *                                   ((int64_t)p_stream->fmt.video.i_height<<16) / VOUT_ASPECT_FACTOR;                    else                        i_width = p_stream->fmt.video.i_width << 16;                    i_height = p_stream->fmt.video.i_height;                    break;                }            }            bo_add_32be( tkhd, i_width );     // width (presentation)            bo_add_32be( tkhd, i_height << 16 );    // height(presentation)        }        box_fix( tkhd );        box_gather( trak, tkhd );        /* *** add /moov/trak/edts and elst */        edts = box_new( "edts" );        elst = box_full_new( "elst", p_sys->b_64_ext ? 1 : 0, 0 );        if( p_stream->i_dts_start > p_sys->i_dts_start )        {            bo_add_32be( elst, 2 );            if( p_sys->b_64_ext )            {                bo_add_64be( elst, (p_stream->i_dts_start-p_sys->i_dts_start) *                             i_movie_timescale / I64C(1000000) );                bo_add_64be( elst, -1 );            }            else            {                bo_add_32be( elst, (p_stream->i_dts_start-p_sys->i_dts_start) *                             i_movie_timescale / I64C(1000000) );                bo_add_32be( elst, -1 );            }            bo_add_16be( elst, 1 );            bo_add_16be( elst, 0 );        }        else        {            bo_add_32be( elst, 1 );        }        if( p_sys->b_64_ext )        {            bo_add_64be( elst, p_stream->i_duration *                         i_movie_timescale / I64C(1000000) );            bo_add_64be( elst, 0 );        }        else

⌨️ 快捷键说明

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