Changeset 94431db895039165b839c35907eb21890b87cc61

Show
Ignore:
Timestamp:
08/14/06 23:44:15 (2 years ago)
Author:
Derk-Jan Hartman <hartman@videolan.org>
git-committer:
Derk-Jan Hartman <hartman@videolan.org> 1155591855 +0000
git-parent:

[7cb0b7cc0d65a44147aa14fd7d7ab11936114ba0]

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

* Victory at last. The h264 packetizer is fixed. Thx to Haali and gibalou for the insights.

  • manage private data properly
  • use 4 byte startcodes
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/packetizer/h264.c

    rbf706ca r94431db  
    122122/***************************************************************************** 
    123123 * Open: probe the packetizer and return score 
     124 * When opening after demux, the packetizer is only loaded AFTER the decoder 
     125 * That means that what you set in fmt_out is ignored by the decoder in this special case 
    124126 *****************************************************************************/ 
    125127static int Open( vlc_object_t *p_this ) 
     
    166168    es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in ); 
    167169    p_dec->fmt_out.i_codec = VLC_FOURCC( 'h', '2', '6', '4' ); 
    168     /* FIXME: FFMPEG isn't happy at all if you leave this */ 
    169     if( p_dec->fmt_out.i_extra ) free( p_dec->fmt_out.p_extra ); 
    170     p_dec->fmt_out.i_extra = 0; p_dec->fmt_out.p_extra = 0; 
    171170 
    172171    if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'v', 'c', '1' ) ) 
    173172    { 
     173        /* This type of stream is produced by mp4 and matroska 
     174         * when we want to store it in another streamformat, you need to convert 
     175         * The fmt_in.p_extra should ALWAYS contain the avcC 
     176         * The fmt_out.p_extra should contain all the SPS and PPS with 4 byte startcodes */ 
    174177        uint8_t *p = &((uint8_t*)p_dec->fmt_in.p_extra)[4]; 
    175178        int i_sps, i_pps; 
     
    181184        /* Read SPS */ 
    182185        i_sps = (*p++)&0x1f; 
    183  
    184186        for( i = 0; i < i_sps; i++ ) 
    185187        { 
     
    207209                 p_sys->i_avcC_length_size, i_sps, i_pps ); 
    208210 
     211        /* FIXME: FFMPEG isn't happy at all if you leave this */ 
     212        if( p_dec->fmt_out.i_extra ) free( p_dec->fmt_out.p_extra ); 
     213        p_dec->fmt_out.i_extra = 0; p_dec->fmt_out.p_extra = NULL; 
     214         
     215        /* Set the new extradata */ 
     216        p_dec->fmt_out.i_extra = p_sys->p_pps->i_buffer + p_sys->p_sps->i_buffer; 
     217        p_dec->fmt_out.p_extra = (uint8_t*)malloc( p_dec->fmt_out.i_extra ); 
     218        memcpy( p_dec->fmt_out.p_extra, p_sys->p_pps->p_buffer, p_sys->p_pps->i_buffer); 
     219        memcpy( p_dec->fmt_out.p_extra+p_sys->p_pps->i_buffer, p_sys->p_sps->p_buffer, p_sys->p_sps->i_buffer); 
     220 
    209221        /* Set callback */ 
    210222        p_dec->pf_packetize = PacketizeAVC1; 
     
    212224    else 
    213225    { 
     226        /* This type of stream contains data with 3 of 4 byte startcodes  
     227         * The fmt_in.p_extra MAY contain SPS/PPS with 4 byte startcodes 
     228         * The fmt_out.p_extra should be the same */ 
     229          
    214230        /* Set callback */ 
    215231        p_dec->pf_packetize = Packetize; 
     
    252268/**************************************************************************** 
    253269 * Packetize: the whole thing 
     270 * Search for the startcodes 3 or more bytes 
     271 * Feed ParseNALBlock ALWAYS with 4 byte startcode prepended NALs 
    254272 ****************************************************************************/ 
    255273static block_t *Packetize( decoder_t *p_dec, block_t **pp_block ) 
     
    267285        { 
    268286            case STATE_NOSYNC: 
     287                /* Skip untill 3 byte startcode 0 0 1 */ 
    269288                if( block_FindStartcodeFromOffset( &p_sys->bytestream, 
    270289                      &p_sys->i_offset, p_sys->startcode+1, 3 ) == VLC_SUCCESS) 
     
    275294                if( p_sys->i_offset ) 
    276295                { 
     296                    /* skip the data */ 
    277297                    block_SkipBytes( &p_sys->bytestream, p_sys->i_offset ); 
    278298                    p_sys->i_offset = 0; 
     
    289309 
    290310            case STATE_NEXT_SYNC: 
    291                 /* Find the next startcode */ 
     311                /* Find the next 3 byte startcode 0 0 1*/ 
    292312                if( block_FindStartcodeFromOffset( &p_sys->bytestream, 
    293313                      &p_sys->i_offset, p_sys->startcode+1, 3 ) != VLC_SUCCESS) 
     
    298318 
    299319                /* Get the new fragment and set the pts/dts */ 
    300                 p_pic = block_New( p_dec, p_sys->i_offset ); 
     320                p_pic = block_New( p_dec, p_sys->i_offset +1 ); 
    301321                p_pic->i_pts = p_sys->bytestream.p_block->i_pts; 
    302322                p_pic->i_dts = p_sys->bytestream.p_block->i_dts; 
    303  
    304                 block_GetBytes( &p_sys->bytestream, p_pic->p_buffer, 
    305                                 p_pic->i_buffer ); 
    306  
    307                 if( !p_pic->p_buffer[p_pic->i_buffer-1] ) p_pic->i_buffer--; 
     323                /* Force 4 byte startcode 0 0 0 1 */ 
     324                p_pic->p_buffer[0] = 0; 
     325 
     326                block_GetBytes( &p_sys->bytestream, &p_pic->p_buffer[1], 
     327                                p_pic->i_buffer-1 ); 
     328 
     329                /* Remove trailing 0 bytes */ 
     330                while( p_pic->i_buffer && (!p_pic->p_buffer[p_pic->i_buffer-1] ) ) p_pic->i_buffer--; 
    308331                p_sys->i_offset = 0; 
    309332 
     
    330353 
    331354/**************************************************************************** 
    332  * PacketizeAVC1: the whole thing 
     355 * PacketizeAVC1: Takes VCL blocks of data and creates annexe B type NAL stream 
     356 * Will always use 4 byte 0 0 0 1 startcodes 
     357 * Should prepend the SPS and PPS to the front of the stream  
    333358 ****************************************************************************/ 
    334359static block_t *PacketizeAVC1( decoder_t *p_dec, block_t **pp_block ) 
     
    395420    block_t *p_nal; 
    396421 
    397     p_nal = block_New( p_dec, 3 + i_size ); 
     422    p_nal = block_New( p_dec, 4 + i_size ); 
    398423 
    399424    /* Add start code */ 
    400425    p_nal->p_buffer[0] = 0x00; 
    401426    p_nal->p_buffer[1] = 0x00; 
    402     p_nal->p_buffer[2] = 0x01; 
     427    p_nal->p_buffer[2] = 0x00; 
     428    p_nal->p_buffer[3] = 0x01; 
    403429 
    404430    /* Copy nalu */ 
    405     memcpy( &p_nal->p_buffer[3], p, i_size ); 
     431    memcpy( &p_nal->p_buffer[4], p, i_size ); 
    406432 
    407433    return p_nal; 
     
    452478 
    453479 
     480/***************************************************************************** 
     481 * ParseNALBlock: parses annexB type NALs 
     482 * All p_frag blocks are required to start with 0 0 0 1 4-byte startcode  
     483 *****************************************************************************/ 
    454484static block_t *ParseNALBlock( decoder_t *p_dec, block_t *p_frag ) 
    455485{ 
     
    457487    block_t *p_pic = NULL; 
    458488 
    459     const int i_nal_ref_idc = (p_frag->p_buffer[3] >> 5)&0x03; 
    460     const int i_nal_type = p_frag->p_buffer[3]&0x1f; 
     489    const int i_nal_ref_idc = (p_frag->p_buffer[4] >> 5)&0x03; 
     490    const int i_nal_type = p_frag->p_buffer[4]&0x1f; 
    461491 
    462492#define OUTPUT \ 
     
    494524 
    495525        /* do not convert the whole frame */ 
    496         nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[4], 
    497                          __MIN( p_frag->i_buffer - 4, 60 ) ); 
     526        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[5], 
     527                         __MIN( p_frag->i_buffer - 5, 60 ) ); 
    498528        bs_init( &s, dec, i_dec ); 
    499529 
     
    574604        p_sys->b_sps = VLC_TRUE; 
    575605 
    576         nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[4], 
    577                          p_frag->i_buffer - 4 ); 
     606        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[5], 
     607                         p_frag->i_buffer - 5 ); 
    578608 
    579609        bs_init( &s, dec, i_dec ); 
     
    686716    { 
    687717        bs_t s; 
    688         bs_init( &s, &p_frag->p_buffer[4], p_frag->i_buffer - 4 ); 
     718        bs_init( &s, &p_frag->p_buffer[5], p_frag->i_buffer - 5 ); 
    689719 
    690720        if( !p_sys->b_pps ) msg_Dbg( p_dec, "found NAL_PPS" );