📄 mp4.c
字号:
bo_t *url; bo_t *stbl; bo_t *stsd; bo_t *stts; bo_t *stsz; p_stream = p_sys->pp_streams[i_trak]; if( p_stream->p_fmt->i_cat != AUDIO_ES && p_stream->p_fmt->i_cat != VIDEO_ES ) { msg_Err( p_mux, "FIXME ignoring trak (noaudio&&novideo)" ); continue; } if( p_stream->p_fmt->i_cat == AUDIO_ES ) { i_timescale = p_stream->p_fmt->i_sample_rate; } else { i_timescale = 1001; } /* *** add /moov/trak *** */ trak = box_new( "trak" ); /* *** add /moov/trak/tkhd *** */ if( p_sys->b_mov ) { 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 { 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 bo_add_16be( tkhd, p_stream->p_fmt->i_cat == AUDIO_ES ? 0x100 : 0 ); // volume bo_add_16be( tkhd, 0 ); // reserved for( i = 0; i < 9; i++ ) { bo_add_32be( tkhd, mvhd_matrix[i] ); // matrix } if( p_stream->p_fmt->i_cat == AUDIO_ES ) { bo_add_32be( tkhd, 0 ); // width (presentation) bo_add_32be( tkhd, 0 ); // height(presentation) } else { bo_add_32be( tkhd, p_stream->p_fmt->i_width << 16 ); // width (presentation) bo_add_32be( tkhd, p_stream->p_fmt->i_height << 16 ); // height(presentation) } box_fix( tkhd ); box_gather( trak, tkhd ); /* *** add /moov/trak/mdia *** */ mdia = box_new( "mdia" ); /* */ if( p_sys->b_mov ) { mdhd = box_full_new( "mdhd", 0, 0 ); bo_add_32be( mdhd, get_timestamp() ); // creation time bo_add_32be( mdhd, get_timestamp() ); // modification time bo_add_32be( mdhd, i_timescale); // timescale bo_add_32be( mdhd, p_stream->i_duration * (int64_t)i_timescale / (mtime_t)1000000 ); // duration } else { mdhd = box_full_new( "mdhd", 1, 0 ); bo_add_64be( mdhd, get_timestamp() ); // creation time bo_add_64be( mdhd, get_timestamp() ); // modification time bo_add_32be( mdhd, i_timescale); // timescale bo_add_64be( mdhd, p_stream->i_duration * (int64_t)i_timescale / (mtime_t)1000000 ); // duration } bo_add_16be( mdhd, 0 ); // language FIXME bo_add_16be( mdhd, 0 ); // predefined box_fix( mdhd ); box_gather( mdia, mdhd ); /* */ hdlr = box_full_new( "hdlr", 0, 0 ); bo_add_32be( hdlr, 0 ); // predefined if( p_stream->p_fmt->i_cat == AUDIO_ES ) { bo_add_fourcc( hdlr, "soun" ); } else { bo_add_fourcc( hdlr, "vide" ); } for( i = 0; i < 3; i++ ) { bo_add_32be( hdlr, 0 ); // reserved } bo_add_mem( hdlr, 2, "?" ); box_fix( hdlr ); box_gather( mdia, hdlr ); /* minf*/ minf = box_new( "minf" ); /* add smhd|vmhd */ if( p_stream->p_fmt->i_cat == AUDIO_ES ) { bo_t *smhd; smhd = box_full_new( "smhd", 0, 0 ); bo_add_16be( smhd, 0 ); // balance bo_add_16be( smhd, 0 ); // reserved box_fix( smhd ); box_gather( minf, smhd ); } else if( p_stream->p_fmt->i_cat == VIDEO_ES ) { bo_t *vmhd; vmhd = box_full_new( "vmhd", 0, 1 ); bo_add_16be( vmhd, 0 ); // graphicsmode for( i = 0; i < 3; i++ ) { bo_add_16be( vmhd, 0 ); // opcolor } box_fix( vmhd ); box_gather( minf, vmhd ); } /* dinf */ dinf = box_new( "dinf" ); dref = box_full_new( "dref", 0, 0 ); bo_add_32be( dref, 1 ); url = box_full_new( "url ", 0, 0x01 ); box_fix( url ); box_gather( dref, url ); box_fix( dref ); box_gather( dinf, dref ); /* append dinf to mdia */ box_fix( dinf ); box_gather( minf, dinf ); /* add stbl */ stbl = box_new( "stbl" ); stsd = box_full_new( "stsd", 0, 0 ); bo_add_32be( stsd, 1 ); if( p_stream->p_fmt->i_cat == AUDIO_ES ) { bo_t *soun; char fcc[4] = " "; int i; vlc_bool_t b_mpeg4_hdr; switch( p_stream->p_fmt->i_fourcc ) { case VLC_FOURCC( 'm', 'p', '4', 'a' ): memcpy( fcc, "mp4a", 4 ); b_mpeg4_hdr = VLC_TRUE; break; case VLC_FOURCC( 'm', 'p', 'g', 'a' ): if( p_sys->b_mov ) memcpy( fcc, ".mp3 ", 4 ); else memcpy( fcc, "mp4a", 4 ); b_mpeg4_hdr = VLC_FALSE; break; default: memcpy( fcc, (char*)&p_stream->p_fmt->i_fourcc, 4 ); b_mpeg4_hdr = VLC_FALSE; 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 bo_add_32be( soun, 0 ); // reserved; bo_add_32be( soun, 0 ); // reserved; bo_add_16be( soun, p_stream->p_fmt->i_channels ); // channel-count bo_add_16be( soun, 16); // FIXME sample size bo_add_16be( soun, 0 ); // predefined bo_add_16be( soun, 0 ); // reserved bo_add_16be( soun, p_stream->p_fmt->i_sample_rate ); // sampleratehi bo_add_16be( soun, 0 ); // sampleratelo /* add an ES Descriptor */ if( b_mpeg4_hdr ) { bo_t *esds; esds = GetESDS( p_stream ); box_fix( esds ); box_gather( soun, esds ); } box_fix( soun ); box_gather( stsd, soun ); } else if( p_stream->p_fmt->i_cat == VIDEO_ES ) { bo_t *vide; char fcc[4] = " "; int i; vlc_bool_t b_mpeg4_hdr; switch( p_stream->p_fmt->i_fourcc ) { case VLC_FOURCC( 'm', 'p', '4', 'v' ): case VLC_FOURCC( 'm', 'p', 'g', 'v' ): memcpy( fcc, "mp4v", 4 ); b_mpeg4_hdr = VLC_TRUE; break; case VLC_FOURCC( 'M', 'J', 'P', 'G' ): memcpy( fcc, "mjpa", 4 ); b_mpeg4_hdr = VLC_FALSE; break; default: memcpy( fcc, (char*)&p_stream->p_fmt->i_fourcc, 4 ); b_mpeg4_hdr = VLC_FALSE; 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->p_fmt->i_width ); // i_width bo_add_16be( vide, p_stream->p_fmt->i_height ); // i_height bo_add_32be( vide, 0x00480000 ); // h 72dpi bo_add_32be( vide, 0x00480000 ); // v 72dpi bo_add_32be( vide, 0 ); // reserved bo_add_16be( vide, 1 ); // predefined for( i = 0; i < 32; i++ ) { bo_add_8( vide, 0 ); // compressor name; } bo_add_16be( vide, 0x18 ); // depth bo_add_16be( vide, 0xffff ); // predefined /* add an ES Descriptor */ if( b_mpeg4_hdr ) { bo_t *esds; esds = GetESDS( p_stream ); box_fix( esds ); box_gather( vide, esds ); } box_fix( vide ); box_gather( stsd, vide ); } /* append stsd to stbl */ box_fix( stsd ); box_gather( stbl, stsd ); /* we will create chunk table and stsc table FIXME optim stsc table FIXME */ i_chunk_count = 0; for( i = 0; i < p_stream->i_entry_count; ) { 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++; } i_chunk_count++; }// if( p_sys->i_pos >= 0xffffffff ) { bo_t *co64; bo_t *stsc; unsigned int i_chunk; msg_Dbg( p_mux, "creating %d chunk (co64)", i_chunk_count ); co64 = box_full_new( "co64", 0, 0 ); bo_add_32be( co64, i_chunk_count ); stsc = box_full_new( "stsc", 0, 0 ); bo_add_32be( stsc, i_chunk_count ); // entry-count for( i_chunk = 0, i = 0; i < p_stream->i_entry_count; i_chunk++ ) { int i_first; bo_add_64be( co64, p_stream->entry[i].i_pos ); i_first = i; 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++; } 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 } /* append co64 to stbl */ box_fix( co64 ); box_gather( stbl, co64 ); /* append stsc to stbl */ box_fix( stsc ); box_gather( stbl, stsc ); }// else// {// FIXME implement it// } /* add stts */ stts = box_full_new( "stts", 0, 0 ); bo_add_32be( stts, 0 ); // fixed latter for( i = 0, i_index = 0; i < p_stream->i_entry_count; i_index++) { int64_t i_delta; int i_first; i_first = i; i_delta = p_stream->entry[i].i_length; while( i < p_stream->i_entry_count ) { if( i + 1 < p_stream->i_entry_count && p_stream->entry[i + 1].i_length != i_delta ) { i++; break; } i++; } bo_add_32be( stts, i - i_first ); // sample-count bo_add_32be( stts, i_delta * (int64_t)i_timescale / (int64_t)1000000 ); // sample-delta } bo_fix_32be( stts, 12, i_index ); /* append stts to stbl */ box_fix( stts ); box_gather( stbl, stts );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -