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

📄 mp4.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 4 页
字号:
        break;    case VLC_FOURCC('m','p','g','a'):        if( p_sys->b_mov )            memcpy( fcc, ".mp3", 4 );        else        {            memcpy( fcc, "mp4a", 4 );            b_descr = VLC_TRUE;        }        break;    default:        memcpy( fcc, (char*)&p_stream->fmt.i_codec, 4 );        break;    }    soun = box_new( fcc );    for( i = 0; i < 6; i++ )    {        bo_add_8( soun, 0 );        // reserved;    }    bo_add_16be( soun, 1 );         // data-reference-index    /* SoundDescription */    if( p_sys->b_mov &&        p_stream->fmt.i_codec == VLC_FOURCC('m','p','4','a') )    {        bo_add_16be( soun, 1 );     // version 1;    }    else    {        bo_add_16be( soun, 0 );     // version 0;    }    bo_add_16be( soun, 0 );         // revision level (0)    bo_add_32be( soun, 0 );         // vendor    // channel-count    bo_add_16be( soun, p_stream->fmt.audio.i_channels );    // sample size    bo_add_16be( soun, p_stream->fmt.audio.i_bitspersample ?                 p_stream->fmt.audio.i_bitspersample : 16 );    bo_add_16be( soun, -2 );        // compression id    bo_add_16be( soun, 0 );         // packet size (0)    bo_add_16be( soun, p_stream->fmt.audio.i_rate ); // sampleratehi    bo_add_16be( soun, 0 );                             // sampleratelo    /* Extended data for SoundDescription V1 */    if( p_sys->b_mov &&        p_stream->fmt.i_codec == VLC_FOURCC('m','p','4','a') )    {        /* samples per packet */        bo_add_32be( soun, p_stream->fmt.audio.i_frame_length );        bo_add_32be( soun, 1536 ); /* bytes per packet */        bo_add_32be( soun, 2 );    /* bytes per frame */        /* bytes per sample */        bo_add_32be( soun, 2 /*p_stream->fmt.audio.i_bitspersample/8 */);    }    /* Add an ES Descriptor */    if( b_descr )    {        bo_t *box;        if( p_sys->b_mov &&            p_stream->fmt.i_codec == VLC_FOURCC('m','p','4','a') )        {            box = GetWaveTag( p_stream );        }        else        {            box = GetESDS( p_stream );        }        box_fix( box );        box_gather( soun, box );    }    box_fix( soun );    return soun;}static bo_t *GetVideBox( sout_mux_t *p_mux, mp4_stream_t *p_stream ){    bo_t *vide;    char fcc[4] = "    ";    int  i;    switch( p_stream->fmt.i_codec )    {    case VLC_FOURCC('m','p','4','v'):    case VLC_FOURCC('m','p','g','v'):        memcpy( fcc, "mp4v", 4 );        break;    case VLC_FOURCC('M','J','P','G'):        memcpy( fcc, "mjpa", 4 );        break;    case VLC_FOURCC('S','V','Q','1'):        memcpy( fcc, "SVQ1", 4 );        break;    case VLC_FOURCC('S','V','Q','3'):        memcpy( fcc, "SVQ3", 4 );        break;    case VLC_FOURCC('h','2','6','4'):        memcpy( fcc, "avc1", 4 );        break;    default:        memcpy( fcc, (char*)&p_stream->fmt.i_codec, 4 );        break;    }    vide = box_new( fcc );    for( i = 0; i < 6; i++ )    {        bo_add_8( vide, 0 );        // reserved;    }    bo_add_16be( vide, 1 );         // data-reference-index    bo_add_16be( vide, 0 );         // predefined;    bo_add_16be( vide, 0 );         // reserved;    for( i = 0; i < 3; i++ )    {        bo_add_32be( vide, 0 );     // predefined;    }    bo_add_16be( vide, p_stream->fmt.video.i_width );  // i_width    bo_add_16be( vide, p_stream->fmt.video.i_height ); // i_height    bo_add_32be( vide, 0x00480000 );                // h 72dpi    bo_add_32be( vide, 0x00480000 );                // v 72dpi    bo_add_32be( vide, 0 );         // data size, always 0    bo_add_16be( vide, 1 );         // frames count per sample    // compressor name;    for( i = 0; i < 32; i++ )    {        bo_add_8( vide, 0 );    }    bo_add_16be( vide, 0x18 );      // depth    bo_add_16be( vide, 0xffff );    // predefined    /* add an ES Descriptor */    switch( p_stream->fmt.i_codec )    {    case VLC_FOURCC('m','p','4','v'):    case VLC_FOURCC('m','p','g','v'):        {            bo_t *esds = GetESDS( p_stream );            box_fix( esds );            box_gather( vide, esds );        }        break;    case VLC_FOURCC('S','V','Q','3'):        {            bo_t *esds = GetSVQ3Tag( p_stream );            box_fix( esds );            box_gather( vide, esds );        }        break;    case VLC_FOURCC('h','2','6','4'):        box_gather( vide, GetAvcCTag( p_stream ) );        break;    default:        break;    }    box_fix( vide );    return vide;}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, "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        }

⌨️ 快捷键说明

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