Changeset 12659dbfad0e0eaeee78aeb91416fcf3732beea6

Show
Ignore:
Timestamp:
27/02/07 21:02:15 (2 years ago)
Author:
Laurent Aimar <fenrir@videolan.org>
git-committer:
Laurent Aimar <fenrir@videolan.org> 1172606535 +0000
git-parent:

[b160af605b251682ad86348cc4e07287084e891c]

git-author:
Laurent Aimar <fenrir@videolan.org> 1172606535 +0000
Message:

Fixed H264 rtp packetization.
Force a TTL value of 1 if not defined instead of refusing to start.
(Any suggestion about a better failsafe value ?)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/stream_out/rtp.c

    r3b75df1 r12659db  
    392392    if( val.i_int < 0 ) 
    393393    { 
    394         msg_Err( p_stream, "illegal TTL %d", val.i_int ); 
    395         free( p_sys ); 
    396         return VLC_EGENERIC; 
     394        msg_Warn( p_stream, "illegal TTL %d, using 1", val.i_int ); 
     395        val.i_int = -1; 
    397396    } 
    398397    p_sys->i_ttl = val.i_int; 
     
    24142413 
    24152414/* rfc3984 */ 
     2415static int rtp_packetize_h264_nal( sout_stream_t *p_stream, sout_stream_id_t *id, 
     2416                                   const uint8_t *p_data, int i_data, int64_t i_pts, int64_t i_dts, vlc_bool_t b_last, int64_t i_length ) 
     2417{ 
     2418    const int i_max = id->i_mtu - 12; /* payload max in one packet */ 
     2419    int i_nal_hdr; 
     2420    int i_nal_type; 
     2421 
     2422    if( i_data < 5 ) 
     2423        return VLC_SUCCESS; 
     2424 
     2425    i_nal_hdr = p_data[3]; 
     2426    i_nal_type = i_nal_hdr&0x1f; 
     2427    if( i_nal_type == 7 || i_nal_type == 8 ) 
     2428    { 
     2429        /* XXX Why do you want to remove them ? It will break streaming with  
     2430         * SPS/PPS change (broadcast) ? */ 
     2431        return VLC_SUCCESS; 
     2432    } 
     2433 
     2434    /* Skip start code */ 
     2435    p_data += 3; 
     2436    i_data -= 3; 
     2437 
     2438    /* */ 
     2439    if( i_data <= i_max ) 
     2440    { 
     2441        /* Single NAL unit packet */ 
     2442        block_t *out = block_New( p_stream, 12 + i_data ); 
     2443        out->i_dts    = i_dts; 
     2444        out->i_length = i_length; 
     2445 
     2446        /* */ 
     2447        rtp_packetize_common( id, out, b_last, i_pts ); 
     2448        out->i_buffer = 12 + i_data; 
     2449 
     2450        memcpy( &out->p_buffer[12], p_data, i_data ); 
     2451 
     2452        rtp_packetize_send( id, out ); 
     2453    } 
     2454    else 
     2455    { 
     2456        /* FU-A Fragmentation Unit without interleaving */ 
     2457        const int i_count = ( i_data-1 + i_max-2 - 1 ) / (i_max-2); 
     2458        int i; 
     2459 
     2460        p_data++; 
     2461        i_data--; 
     2462 
     2463        for( i = 0; i < i_count; i++ ) 
     2464        { 
     2465            const int i_payload = __MIN( i_data, i_max-2 ); 
     2466            block_t *out = block_New( p_stream, 12 + 2 + i_payload ); 
     2467            out->i_dts    = i_dts + i * i_length / i_count; 
     2468            out->i_length = i_length / i_count; 
     2469 
     2470            fprintf( stderr, "FU-A: payload=%d hdr=0x%x\n", i_payload, i_nal_hdr); 
     2471 
     2472            /* */ 
     2473            rtp_packetize_common( id, out, (b_last && i_payload == i_data), i_pts ); 
     2474            out->i_buffer = 14 + i_payload; 
     2475 
     2476            /* FU indicator */ 
     2477            out->p_buffer[12] = 0x00 | (i_nal_hdr & 0x60) | 28; 
     2478            /* FU header */ 
     2479            out->p_buffer[13] = ( i == 0 ? 0x80 : 0x00 ) | ( (i == i_count-1) ? 0x40 : 0x00 )  | i_nal_type; 
     2480            memcpy( &out->p_buffer[14], p_data, i_payload ); 
     2481 
     2482            rtp_packetize_send( id, out ); 
     2483 
     2484            i_data -= i_payload; 
     2485            p_data += i_payload; 
     2486        } 
     2487    } 
     2488    return VLC_SUCCESS; 
     2489} 
     2490 
    24162491static int rtp_packetize_h264( sout_stream_t *p_stream, sout_stream_id_t *id, 
    24172492                               block_t *in ) 
    24182493{ 
    2419     int     i_max   = id->i_mtu - 12; /* payload max in one packet */ 
    2420     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max; 
    2421     uint8_t *p_data = in->p_buffer; 
    2422     int     i_data  = in->i_buffer; 
    2423     block_t *out; 
    2424     int     i_nal_type; 
    2425     int     i_payload; 
    2426  
    2427     while( i_data > 5 && 
    2428            ( p_data[0] != 0x00 || p_data[1] != 0x00 || p_data[2] != 0x01 || /* startcode */ 
    2429             (p_data[3]&0x1f) < 1 || (p_data[3]&0x1f) > 23 ) ) /* naltype should be between 1 and 23 */ 
    2430     { 
    2431         p_data++; 
    2432         i_data--; 
    2433     } 
    2434  
    2435     if( i_data < 5 ) 
    2436         return VLC_SUCCESS; 
    2437  
    2438     p_data+=3; 
    2439     i_data-=3; 
    2440     i_nal_type = p_data[0]&0x1f; 
    2441  
    2442     /* Skip global headers */ 
    2443     if( i_nal_type == 7 || i_nal_type == 8 ) 
    2444         return VLC_SUCCESS; 
    2445      
    2446     if( i_data <= i_max ) /* The whole pack will fit in one rtp payload */ 
    2447     { 
    2448         /* single NAL */ 
    2449         i_payload = __MIN( i_max, i_data ); 
    2450         out = block_New( p_stream, 12 + i_payload ); 
    2451  
    2452         /* rtp common header */ 
    2453         rtp_packetize_common( id, out, 1, 
    2454                               in->i_pts > 0 ? in->i_pts : in->i_dts ); 
    2455  
    2456         memcpy( &out->p_buffer[12], p_data, i_payload ); 
    2457  
    2458         out->i_buffer   = 12 + i_payload; 
    2459         out->i_dts    = in->i_dts; 
    2460         out->i_length = in->i_length; 
    2461  
    2462         rtp_packetize_send( id, out ); 
    2463  
    2464         /*msg_Dbg( p_stream, "nal-out plain %d %02x", i_payload, out->p_buffer[16] );*/ 
    2465     } 
    2466     else 
    2467     { 
    2468         /* FU-A */ 
    2469         uint8_t     nalh; /* The nalheader byte */ 
    2470         int i=0, start=1, end=0, first=0; 
    2471   
    2472         nalh = *p_data; 
    2473         p_data++; 
    2474         i_data--; 
    2475  
    2476         i_max   = id->i_mtu - 14; 
    2477         i_count = ( i_data + i_max - 1 ) / i_max; 
    2478  
    2479         /*msg_Dbg( p_stream, "nal-out fragmented %02x %d", nalh, i_rest);*/ 
    2480  
    2481         while( end == 0 ) 
    2482         { 
    2483             i_payload = __MIN( i_max, i_data ); 
    2484             out = block_New( p_stream, 14 + i_payload ); 
    2485  
    2486             if( i_data == i_payload ) 
    2487                 end = 1; 
    2488  
    2489             /* rtp common header */ 
    2490             rtp_packetize_common( id, out, (end)?1:0, 
    2491                               in->i_pts > 0 ? in->i_pts : in->i_dts ); 
    2492  
    2493             /* FU indicator */ 
    2494             out->p_buffer[12] = (nalh&0x60)|28; 
    2495             /* FU header */ 
    2496             out->p_buffer[13] = (start<<7)|(end<<6)|(nalh&0x1f); 
    2497  
    2498             memcpy( &out->p_buffer[14], p_data+first, i_payload ); 
    2499   
    2500             out->i_buffer   = 14 + i_payload; 
    2501  
    2502             // not sure what of these should be used and what it does :) 
    2503             out->i_pts    = in->i_pts; 
    2504             out->i_dts    = in->i_dts; 
    2505             //out->i_dts    = in->i_dts + i * in->i_length / i_count; 
    2506             //out->i_length = in->i_length / i_count; 
    2507  
    2508             rtp_packetize_send( id, out ); 
    2509  
    2510             /*msg_Dbg( p_stream, "nal-out fragmented: frag %d %d %02x %02x %d", start,end, 
    2511             out->p_buffer[12], out->p_buffer[13], i_payload );*/ 
    2512  
    2513             i_data -= i_payload; 
    2514             first += i_payload; 
    2515             i++; 
    2516             start=0; 
    2517         } 
     2494    const uint8_t *p_buffer = in->p_buffer; 
     2495    int i_buffer = in->i_buffer; 
     2496 
     2497    while( i_buffer > 4 && ( p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] != 1 ) ) 
     2498    { 
     2499        i_buffer--; 
     2500        p_buffer++; 
     2501    } 
     2502 
     2503    /* Split nal units */ 
     2504    while( i_buffer > 4 ) 
     2505    { 
     2506        int i_offset; 
     2507        int i_size = i_buffer; 
     2508        int i_skip = i_buffer; 
     2509 
     2510        /* search nal end */ 
     2511        for( i_offset = 4; i_offset+2 < i_buffer ; i_offset++) 
     2512        { 
     2513            if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 1 ) 
     2514            { 
     2515                /* we found another startcode */ 
     2516                i_size = i_offset - ( p_buffer[i_offset-1] == 0 ? 1 : 0); 
     2517                i_skip = i_offset; 
     2518                break; 
     2519            }  
     2520        } 
     2521        /* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */ 
     2522        rtp_packetize_h264_nal( p_stream, id, p_buffer, i_size, 
     2523                                (in->i_pts > 0 ? in->i_pts : in->i_dts), in->i_dts, 
     2524                                (i_size >= i_buffer), in->i_length * i_size / in->i_buffer ); 
     2525 
     2526        i_buffer -= i_skip; 
     2527        p_buffer += i_skip; 
    25182528    } 
    25192529    return VLC_SUCCESS;