📄 mp4.c
字号:
wave = box_new( "wave" ); box = box_new( "frma" ); bo_add_fourcc( box, "mp4a" ); box_fix( box ); box_gather( wave, box ); box = box_new( "mp4a" ); bo_add_32be( box, 0 ); box_fix( box ); box_gather( wave, box ); box = GetESDS( p_stream ); box_fix( box ); box_gather( wave, box ); box = box_new( "srcq" ); bo_add_32be( box, 0x40 ); box_fix( box ); box_gather( wave, box ); /* wazza ? */ bo_add_32be( wave, 8 ); /* new empty box */ bo_add_32be( wave, 0 ); /* box label */ box_fix( wave ); return wave;}static bo_t *GetDamrTag( mp4_stream_t *p_stream ){ bo_t *damr; damr = box_new( "damr" ); bo_add_fourcc( damr, "REFC" ); bo_add_8( damr, 0 ); if( p_stream->fmt.i_codec == VLC_FOURCC( 's', 'a', 'm', 'r' ) ) bo_add_16be( damr, 0x81ff ); /* Mode set (all modes for AMR_NB) */ else bo_add_16be( damr, 0x83ff ); /* Mode set (all modes for AMR_WB) */ bo_add_16be( damr, 0x1 ); /* Mode change period (no restriction) */ box_fix( damr ); return damr;}static bo_t *GetD263Tag( mp4_stream_t *p_stream ){ bo_t *d263; d263 = box_new( "d263" ); bo_add_fourcc( d263, "VLC " ); bo_add_16be( d263, 0xa ); bo_add_8( d263, 0 ); box_fix( d263 ); return d263;}static bo_t *GetAvcCTag( mp4_stream_t *p_stream ){ bo_t *avcC; /* FIXME use better value */ avcC = box_new( "avcC" ); bo_add_8( avcC, 1 ); /* configuration version */ bo_add_8( avcC, p_stream->avc.i_profile ); bo_add_8( avcC, p_stream->avc.i_profile_compat ); bo_add_8( avcC, p_stream->avc.i_level ); /* level, 5.1 */ bo_add_8( avcC, 0xff ); /* 0b11111100 | lengthsize = 0x11 */ bo_add_8( avcC, 0xe0 | (p_stream->avc.i_sps > 0 ? 1 : 0) ); /* 0b11100000 | sps_count */ if( p_stream->avc.i_sps > 0 ) { bo_add_16be( avcC, p_stream->avc.i_sps ); bo_add_mem( avcC, p_stream->avc.i_sps, p_stream->avc.sps ); } bo_add_8( avcC, (p_stream->avc.i_pps > 0 ? 1 : 0) ); /* pps_count */ if( p_stream->avc.i_pps > 0 ) { bo_add_16be( avcC, p_stream->avc.i_pps ); bo_add_mem( avcC, p_stream->avc.i_pps, p_stream->avc.pps ); } box_fix( avcC ); return avcC;}/* TODO: No idea about these values */static bo_t *GetSVQ3Tag( mp4_stream_t *p_stream ){ bo_t *smi = box_new( "SMI " ); if( p_stream->fmt.i_extra > 0x4e ) { uint8_t *p_end = &((uint8_t*)p_stream->fmt.p_extra)[p_stream->fmt.i_extra]; uint8_t *p = &((uint8_t*)p_stream->fmt.p_extra)[0x46]; while( p + 8 < p_end ) { int i_size = GetDWBE( p ); if( i_size <= 1 ) { /* FIXME handle 1 as long size */ break; } if( !strncmp( (const char *)&p[4], "SMI ", 4 ) ) { bo_add_mem( smi, p_end - p - 8, &p[8] ); return smi; } p += i_size; } } /* Create a dummy one in fallback */ bo_add_fourcc( smi, "SEQH" ); bo_add_32be( smi, 0x5 ); bo_add_32be( smi, 0xe2c0211d ); bo_add_8( smi, 0xc0 ); box_fix( smi ); return smi;}static bo_t *GetUdtaTag( sout_mux_t *p_mux ){ sout_mux_sys_t *p_sys = p_mux->p_sys; bo_t *udta = box_new( "udta" ); vlc_meta_t *p_meta = p_mux->p_sout->p_meta; int i_track; /* Requirements */ for( i_track = 0; i_track < p_sys->i_nb_streams; i_track++ ) { mp4_stream_t *p_stream = p_sys->pp_streams[i_track]; if( p_stream->fmt.i_codec == VLC_FOURCC('m','p','4','v') || p_stream->fmt.i_codec == VLC_FOURCC('m','p','4','a') ) { bo_t *box = box_new( "\251req" ); /* String length */ bo_add_16be( box, sizeof("QuickTime 6.0 or greater") - 1); bo_add_16be( box, 0 ); bo_add_mem( box, sizeof("QuickTime 6.0 or greater") - 1, (uint8_t *)"QuickTime 6.0 or greater" ); box_fix( box ); box_gather( udta, box ); break; } } /* Encoder */ { bo_t *box = box_new( "\251enc" ); /* String length */ bo_add_16be( box, sizeof(PACKAGE_STRING " stream output") - 1); bo_add_16be( box, 0 ); bo_add_mem( box, sizeof(PACKAGE_STRING " stream output") - 1, (uint8_t*)PACKAGE_STRING " stream output" ); box_fix( box ); box_gather( udta, box ); } /* Misc atoms */ if( p_meta ) { int i; for( i = 0; i < p_meta->i_meta; i++ ) { bo_t *box = NULL; if( !strcmp( p_meta->name[i], VLC_META_TITLE ) ) box = box_new( "\251nam" ); else if( !strcmp( p_meta->name[i], VLC_META_AUTHOR ) ) box = box_new( "\251aut" ); else if( !strcmp( p_meta->name[i], VLC_META_ARTIST ) ) box = box_new( "\251ART" ); else if( !strcmp( p_meta->name[i], VLC_META_GENRE ) ) box = box_new( "\251gen" ); else if( !strcmp( p_meta->name[i], VLC_META_COPYRIGHT ) ) box = box_new( "\251cpy" ); else if( !strcmp( p_meta->name[i], VLC_META_DESCRIPTION ) ) box = box_new( "\251des" ); else if( !strcmp( p_meta->name[i], VLC_META_DATE ) ) box = box_new( "\251day" ); else if( !strcmp( p_meta->name[i], VLC_META_URL ) ) box = box_new( "\251url" ); if( box ) { bo_add_16be( box, strlen( p_meta->value[i] ) ); bo_add_16be( box, 0 ); bo_add_mem( box, strlen( p_meta->value[i] ), (uint8_t*)(p_meta->value[i]) ); box_fix( box ); box_gather( udta, box ); } } } box_fix( udta ); return udta;}static bo_t *GetSounBox( sout_mux_t *p_mux, mp4_stream_t *p_stream ){ sout_mux_sys_t *p_sys = p_mux->p_sys; vlc_bool_t b_descr = VLC_FALSE; bo_t *soun; char fcc[4] = " "; int i; switch( p_stream->fmt.i_codec ) { case VLC_FOURCC('m','p','4','a'): memcpy( fcc, "mp4a", 4 ); b_descr = VLC_TRUE; break; case VLC_FOURCC('s','a','m','r'): case VLC_FOURCC('s','a','w','b'): memcpy( fcc, (char*)&p_stream->fmt.i_codec, 4 ); b_descr = 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_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 if( p_stream->fmt.i_codec == VLC_FOURCC('s','a','m','r') ) { box = GetDamrTag( 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','3'): memcpy( fcc, "s263", 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('H','2','6','3'): { bo_t *d263 = GetD263Tag( p_stream ); box_fix( d263 ); box_gather( vide, d263 ); } 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -