Changeset e987d21394a1c2a065bb1744dc84a91b29b37e06

Show
Ignore:
Timestamp:
10/08/06 12:31:37 (2 years ago)
Author:
Derk-Jan Hartman <hartman@videolan.org>
git-committer:
Derk-Jan Hartman <hartman@videolan.org> 1160303497 +0000
git-parent:

[7a8c59f79b581b8e36510348f8b2d7e37aeef486]

git-author:
Derk-Jan Hartman <hartman@videolan.org> 1160303497 +0000
Message:

* Skip h264 SPS/PPS in bitstream when muxing mp4

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/mux/mp4.c

    r62fffad re987d21  
    115115    vlc_bool_t b_stco64; 
    116116 
    117     /* for h264 */ 
    118     struct 
    119     { 
    120         int     i_profile; 
    121         int     i_profile_compat; 
    122         int     i_level; 
    123  
    124         int     i_sps; 
    125         uint8_t *sps; 
    126         int     i_pps; 
    127         uint8_t *pps; 
    128     } avc; 
    129  
    130117    /* for spu */ 
    131118    int64_t i_last_dts; 
     
    185172 
    186173static block_t *ConvertSUBT( sout_mux_t *, mp4_stream_t *, block_t *); 
    187 static void ConvertAVC1( sout_mux_t *, mp4_stream_t *, block_t * ); 
     174static block_t *ConvertAVC1( sout_mux_t *, mp4_stream_t *, block_t * ); 
    188175 
    189176/***************************************************************************** 
     
    365352 
    366353        es_format_Clean( &p_stream->fmt ); 
    367         if( p_stream->avc.i_sps ) free( p_stream->avc.sps ); 
    368         if( p_stream->avc.i_pps ) free( p_stream->avc.pps ); 
    369354        free( p_stream->entry ); 
    370355        free( p_stream ); 
     
    441426    p_stream->i_dts_start   = 0; 
    442427    p_stream->i_duration    = 0; 
    443     p_stream->avc.i_profile = 77; 
    444     p_stream->avc.i_profile_compat = 64; 
    445     p_stream->avc.i_level   = 30; 
    446     p_stream->avc.i_sps     = 0; 
    447     p_stream->avc.sps       = NULL; 
    448     p_stream->avc.i_pps     = 0; 
    449     p_stream->avc.pps       = NULL; 
    450428 
    451429    p_input->p_sys          = p_stream; 
     
    528506        p_stream = (mp4_stream_t*)p_input->p_sys; 
    529507 
     508again: 
    530509        p_data  = block_FifoGet( p_input->p_fifo ); 
    531510        if( p_stream->fmt.i_codec == VLC_FOURCC( 'h', '2', '6', '4' ) ) 
    532511        { 
    533             ConvertAVC1( p_mux, p_stream, p_data ); 
     512            p_data = ConvertAVC1( p_mux, p_stream, p_data ); 
    534513        } 
    535514        else if( p_stream->fmt.i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) ) 
     
    537516            p_data = ConvertSUBT( p_mux, p_stream, p_data ); 
    538517        } 
     518        if( p_data == NULL ) goto again; 
    539519 
    540520        if( p_stream->fmt.i_cat != SPU_ES ) 
     
    683663} 
    684664 
    685 static void ConvertAVC1( sout_mux_t *p_mux, mp4_stream_t *tk, block_t *p_block ) 
     665static block_t *ConvertAVC1( sout_mux_t *p_mux, mp4_stream_t *tk, block_t *p_block ) 
    686666{ 
    687667    uint8_t *last = p_block->p_buffer;  /* Assume it starts with 0x00000001 */ 
     
    717697        last[3] = ( i_size       )&0xff; 
    718698 
    719         if( (last[4]&0x1f) == 7 && tk->avc.i_sps <= 0 )  /* SPS */ 
    720         { 
    721             tk->avc.i_sps = i_size; 
    722             tk->avc.sps = malloc( i_size ); 
    723             memcpy( tk->avc.sps, &last[4], i_size ); 
    724  
    725             tk->avc.i_profile = tk->avc.sps[1]; 
    726             tk->avc.i_profile = tk->avc.sps[2]; 
    727             tk->avc.i_level   = tk->avc.sps[3]; 
    728         } 
    729         else if( (last[4]&0x1f) == 8 && tk->avc.i_pps <= 0 )   /* PPS */ 
    730         { 
    731             tk->avc.i_pps = i_size; 
    732             tk->avc.pps = malloc( i_size ); 
    733             memcpy( tk->avc.pps, &last[4], i_size ); 
    734         } 
     699        /* Skip blocks with SPS/PPS */  
     700        if( (last[4]&0x1f) == 7 || (last[4]&0x1f) == 8 ) 
     701            p_block->i_buffer = 0; 
    735702 
    736703        last = dat; 
    737  
    738704        dat += 4; 
    739705    } 
     706    return p_block; 
    740707} 
    741708 
     
    927894static bo_t *GetAvcCTag( mp4_stream_t *p_stream ) 
    928895{ 
    929     bo_t *avcC; 
    930  
     896    bo_t    *avcC = NULL; 
     897    uint8_t *p_sps = NULL; 
     898    uint8_t *p_pps = NULL; 
     899    int     i_sps_size = 0; 
     900    int     i_pps_size = 0; 
     901 
     902    if( p_stream->fmt.i_extra > 0 ) 
     903    { 
     904        /* FIXME: take into account multiple sps/pps */ 
     905        uint8_t *p_buffer = p_stream->fmt.p_extra; 
     906        int     i_buffer = p_stream->fmt.i_extra; 
     907 
     908        while( i_buffer > 4 &&  
     909            p_buffer[0] == 0 && p_buffer[1] == 0 && 
     910            p_buffer[2] == 0 && p_buffer[3] == 1 ) 
     911        { 
     912            const int i_nal_type = p_buffer[4]&0x1f; 
     913            int i_offset    = 1; 
     914            int i_size      = 0; 
     915            int i_startcode = 0; 
     916             
     917            //msg_Dbg( p_stream, "we found a startcode for NAL with TYPE:%d", i_nal_type ); 
     918             
     919            for( i_offset = 1; i_offset+3 < i_buffer ; i_offset++) 
     920            { 
     921                if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 &&  
     922                    p_buffer[i_offset+2] == 0 && p_buffer[i_offset+3] == 1 ) 
     923                { 
     924                    /* we found another startcode */ 
     925                    i_startcode = i_offset; 
     926                    break; 
     927                }  
     928            } 
     929            i_size = i_startcode ? i_startcode : i_buffer; 
     930            if( i_nal_type == 7 ) 
     931            { 
     932                p_sps = &p_buffer[4]; 
     933                i_sps_size = i_size - 4; 
     934            } 
     935            if( i_nal_type == 8 ) 
     936            { 
     937                p_pps = &p_buffer[4]; 
     938                i_pps_size = i_size - 4; 
     939            } 
     940            i_buffer -= i_size; 
     941            p_buffer += i_size; 
     942        } 
     943    } 
     944     
    931945    /* FIXME use better value */ 
    932946    avcC = box_new( "avcC" ); 
    933947    bo_add_8( avcC, 1 );      /* configuration version */ 
    934     bo_add_8( avcC, p_stream->avc.i_profile ); 
    935     bo_add_8( avcC, p_stream->avc.i_profile_compat ); 
    936     bo_add_8( avcC, p_stream->avc.i_level );       /* level, 5.1 */ 
     948    bo_add_8( avcC, i_sps_size ? p_sps[1] : 77 ); 
     949    bo_add_8( avcC, i_sps_size ? p_sps[2] : 64 ); 
     950    bo_add_8( avcC, i_sps_size ? p_sps[3] : 30 );       /* level, 5.1 */ 
    937951    bo_add_8( avcC, 0xff );   /* 0b11111100 | lengthsize = 0x11 */ 
    938952 
    939     bo_add_8( avcC, 0xe0 | (p_stream->avc.i_sps > 0 ? 1 : 0) );   /* 0b11100000 | sps_count */ 
    940     if( p_stream->avc.i_sps > 0 ) 
    941     { 
    942         bo_add_16be( avcC, p_stream->avc.i_sps ); 
    943         bo_add_mem( avcC, p_stream->avc.i_sps, p_stream->avc.sps ); 
    944     } 
    945  
    946     bo_add_8( avcC, (p_stream->avc.i_pps > 0 ? 1 : 0) );   /* pps_count */ 
    947     if( p_stream->avc.i_pps > 0 ) 
    948     { 
    949         bo_add_16be( avcC, p_stream->avc.i_pps ); 
    950         bo_add_mem( avcC, p_stream->avc.i_pps, p_stream->avc.pps ); 
     953    bo_add_8( avcC, 0xe0 | (i_sps_size > 0 ? 1 : 0) );   /* 0b11100000 | sps_count */ 
     954    if( i_sps_size > 0 ) 
     955    { 
     956        bo_add_16be( avcC, i_sps_size ); 
     957        bo_add_mem( avcC, i_sps_size, p_sps ); 
     958    } 
     959 
     960    bo_add_8( avcC, (i_pps_size > 0 ? 1 : 0) );   /* pps_count */ 
     961    if( i_pps_size > 0 ) 
     962    { 
     963        bo_add_16be( avcC, i_pps_size ); 
     964        bo_add_mem( avcC, i_pps_size, p_pps ); 
    951965    } 
    952966    box_fix( avcC );