Changeset aa5fe86aed9096e92e1f4b0affbb4f6c0c6080ff

Show
Ignore:
Timestamp:
05/06/08 20:12:18 (4 months ago)
Author:
Ilkka Ollakka <ileoo@videolan.org>
git-committer:
Ilkka Ollakka <ileoo@videolan.org> 1210097538 +0300
git-parent:

[fb19b264f8a5fe4ebb47f863e0f040f2ffe9b0a5]

git-author:
Miguel Angel Cabrera Moya <madmac2501@gmail.com> 1210022919 +0200
Message:

RTMP bugfix and reusability enhacenment

Signed-off-by: Ilkka Ollakka <ileoo@videolan.org>

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/access/rtmp/access.c

    r6da90a1 raa5fe86  
    8383    int i; 
    8484 
     85    /*DOWN: 
     86    p_access->info.i_update = 0; 
     87    p_access->info.i_size = 0; 
     88    p_access->info.i_pos = 0; 
     89    p_access->info.b_eof = false; 
     90    p_access->info.i_title = 0; 
     91    p_access->info.i_seekpoint = 0; 
     92    p_access->pf_read = Read; 
     93    p_access->pf_block = Block; 
     94    p_access->pf_control = Control; 
     95    p_access->pf_seek = Seek; 
     96    do 
     97    { 
     98        p_access->p_sys = (access_sys_t *) malloc( sizeof( access_sys_t ) ); 
     99        if( !p_access->p_sys ) 
     100            return VLC_ENOMEM; 
     101    } while(0); 
     102    p_sys = p_access->p_sys; 
     103    memset( p_sys, 0, sizeof( access_sys_t ) ); 
     104    */ 
    85105    STANDARD_READ_ACCESS_INIT 
     106 
     107    p_sys->p_thread = 
     108        vlc_object_create( p_access, sizeof( rtmp_control_thread_t ) ); 
     109    if( !p_sys->p_thread ) 
     110    { 
     111        msg_Err( p_access, "out of memory" ); 
     112        return VLC_ENOMEM; 
     113    } 
     114    vlc_object_attach( p_sys->p_thread, p_access ); 
    86115 
    87116    /* Parse URI - remove spaces */ 
     
    89118    while( (p = strchr( p, ' ' )) != NULL ) 
    90119        *p = '+'; 
    91     vlc_UrlParse( &p_sys->url, psz, 0 ); 
     120    vlc_UrlParse( &p_sys->p_thread->url, psz, 0 ); 
    92121    free( psz ); 
    93122 
    94     if( !p_access->psz_access || 
    95         strncmp( p_access->psz_access, "rtmp", 4 )) 
    96     {    
    97          msg_Warn( p_access, "invalid protocol" ); 
    98          vlc_UrlClean( &p_sys->url ); 
    99          free( p_sys ); 
    100          return VLC_EGENERIC; 
    101     } 
    102  
    103     if( p_sys->url.psz_host == NULL || *p_sys->url.psz_host == '\0' ) 
    104     { 
    105          msg_Warn( p_access, "invalid host" ); 
    106          vlc_UrlClean( &p_sys->url ); 
    107          free( p_sys ); 
    108          return VLC_EGENERIC; 
    109     } 
    110  
    111     if( p_sys->url.i_port <= 0 ) 
    112         p_sys->url.i_port = 1935; 
    113  
    114     if ( p_sys->url.psz_path == NULL ) { 
     123    if( p_sys->p_thread->url.psz_host == NULL 
     124        || *p_sys->p_thread->url.psz_host == '\0' ) 
     125    { 
     126        msg_Warn( p_access, "invalid host" ); 
     127        goto error; 
     128    } 
     129 
     130    if( p_sys->p_thread->url.i_port <= 0 ) 
     131        p_sys->p_thread->url.i_port = 1935; 
     132 
     133    if( p_sys->p_thread->url.psz_path == NULL ) 
     134    { 
    115135        msg_Warn( p_access, "invalid path" ); 
    116         vlc_UrlClean( &p_sys->url ); 
    117         free( p_sys ); 
    118         return VLC_EGENERIC; 
    119     } 
    120  
    121     length_path = strlen( p_sys->url.psz_path ); 
    122     length_media_name = strlen( strrchr( p_sys->url.psz_path, '/' ) ) - 1; 
    123  
    124     p_sys->psz_application = strndup( p_sys->url.psz_path + 1, length_path - length_media_name - 2 ); 
    125     p_sys->psz_media = strdup( p_sys->url.psz_path + ( length_path - length_media_name ) ); 
     136        goto error; 
     137    } 
     138 
     139    length_path = strlen( p_sys->p_thread->url.psz_path ); 
     140    length_media_name = strlen( strrchr( p_sys->p_thread->url.psz_path, '/' ) ) - 1; 
     141 
     142    p_sys->p_thread->psz_application = strndup( p_sys->p_thread->url.psz_path + 1, length_path - length_media_name - 2 ); 
     143    p_sys->p_thread->psz_media = strdup( p_sys->p_thread->url.psz_path + ( length_path - length_media_name ) ); 
    126144 
    127145    msg_Dbg( p_access, "rtmp: host='%s' port=%d path='%s'", 
    128              p_sys->url.psz_host, p_sys->url.i_port, p_sys->url.psz_path ); 
    129  
    130     if( p_sys->url.psz_username && *p_sys->url.psz_username ) 
     146             p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port, p_sys->p_thread->url.psz_path ); 
     147 
     148    if( p_sys->p_thread->url.psz_username && *p_sys->p_thread->url.psz_username ) 
    131149    { 
    132150        msg_Dbg( p_access, "      user='%s', pwd='%s'", 
    133                  p_sys->url.psz_username, p_sys->url.psz_password ); 
    134     } 
    135  
    136     p_sys->p_thread = 
    137         vlc_object_create( p_access, sizeof( rtmp_control_thread_t ) ); 
    138     if( !p_sys->p_thread ) 
    139     { 
    140         msg_Err( p_access, "out of memory" ); 
    141         vlc_UrlClean( &p_sys->url ); 
    142         free( p_sys ); 
    143         return VLC_EGENERIC; 
    144     } 
    145  
    146     vlc_object_attach( p_sys->p_thread, p_access ); 
     151                 p_sys->p_thread->url.psz_username, p_sys->p_thread->url.psz_password ); 
     152    } 
     153 
     154    /* Initialize thread variables */ 
    147155    p_sys->p_thread->b_die = 0; 
    148156    p_sys->p_thread->b_error= 0; 
    149     p_sys->p_thread->p_fifo_media = block_FifoNew(); 
     157    p_sys->p_thread->p_fifo_input = block_FifoNew(); 
    150158    p_sys->p_thread->p_empty_blocks = block_FifoNew(); 
    151159    p_sys->p_thread->has_audio = 0; 
     
    154162    p_sys->p_thread->first_media_packet = 1; 
    155163    p_sys->p_thread->flv_tag_previous_tag_size = 0x00000000; /* FLV_TAG_FIRST_PREVIOUS_TAG_SIZE */ 
     164    p_sys->p_thread->chunk_size_recv = 128; /* RTMP_DEFAULT_CHUNK_SIZE */ 
     165    p_sys->p_thread->chunk_size_send = 128; /* RTMP_DEFAULT_CHUNK_SIZE */ 
    156166    for(i = 0; i < 64; i++) 
    157167    { 
     
    168178    } 
    169179 
     180    p_sys->p_thread->p_base_object = p_this; 
     181 
    170182    vlc_cond_init( p_sys->p_thread, &p_sys->p_thread->wait ); 
     183 
    171184    vlc_mutex_init( &p_sys->p_thread->lock ); 
    172185 
    173186    p_sys->p_thread->result_connect = 1; 
    174187    p_sys->p_thread->result_play = 1; 
     188    p_sys->p_thread->result_stop = 0; 
    175189 
    176190    /* Open connection */ 
    177     p_sys->fd = net_ConnectTCP( p_access, p_sys->url.psz_host, p_sys->url.i_port ); 
    178     p_sys->p_thread->fd = p_sys->fd; 
    179     if( p_sys->fd == -1 ) 
     191    p_sys->p_thread->fd = net_ConnectTCP( p_access, p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port ); 
     192    if( p_sys->p_thread->fd == -1 ) 
    180193    { 
    181194        int *p_fd_listen; 
    182195 
    183         msg_Warn( p_access, "cannot connect to %s:%d", p_sys->url.psz_host, p_sys->url.i_port ); 
     196        msg_Warn( p_access, "cannot connect to %s:%d", p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port ); 
    184197        msg_Dbg( p_access, "switching to passive mode" ); 
    185198 
    186199        p_sys->active = 0; 
    187200 
    188         p_fd_listen = net_ListenTCP( p_access, p_sys->url.psz_host, p_sys->url.i_port ); 
     201        p_fd_listen = net_ListenTCP( p_access, p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port ); 
    189202        if( p_fd_listen == NULL ) 
    190203        { 
    191             msg_Warn( p_access, "cannot listen to %s port %i", p_sys->url.psz_host, p_sys->url.i_port ); 
    192             vlc_UrlClean( &p_sys->url ); 
    193             net_Close( p_sys-> fd ); 
    194             free( p_sys ); 
    195             return VLC_EGENERIC; 
    196         } 
    197  
    198         p_sys->fd = net_Accept( p_access, p_fd_listen, -1 ); 
     204            msg_Err( p_access, "cannot listen to %s port %i", p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port ); 
     205            goto error2; 
     206        } 
     207 
     208        p_sys->p_thread->fd = net_Accept( p_access, p_fd_listen, -1 ); 
    199209 
    200210        net_ListenClose( p_fd_listen ); 
    201211 
    202         if( rtmp_handshake_passive( p_this ) < 0 ) 
    203         { 
    204             msg_Err( p_access, "Passive handshake failed"); 
    205             vlc_UrlClean( &p_sys->url ); 
    206             net_Close( p_sys-> fd ); 
    207             free( p_sys ); 
    208             return VLC_EGENERIC; 
     212        if( rtmp_handshake_passive( p_this, p_sys->p_thread->fd ) < 0 ) 
     213        { 
     214            msg_Err( p_access, "handshake passive failed"); 
     215            goto error2; 
    209216        } 
    210217 
    211218        p_sys->p_thread->result_publish = 1; 
    212  
    213219    } 
    214220    else 
    215221    { 
    216         msg_Dbg( p_access, "using active connection"); 
    217222        p_sys->active = 1; 
    218223 
    219         if( rtmp_handshake_active( p_this ) < 0 ) 
    220         { 
    221             msg_Err( p_access, "Active handshake failed"); 
    222             vlc_UrlClean( &p_sys->url ); 
    223             net_Close( p_sys-> fd ); 
    224             free( p_sys ); 
    225             return VLC_EGENERIC; 
     224        if( rtmp_handshake_active( p_this, p_sys->p_thread->fd ) < 0 ) 
     225        { 
     226            msg_Err( p_access, "handshake active failed"); 
     227            goto error2; 
    226228        } 
    227229 
     
    233235    { 
    234236        msg_Err( p_access, "cannot spawn rtmp control thread" ); 
    235         vlc_UrlClean( &p_sys->url ); 
    236         net_Close( p_sys-> fd ); 
    237         free( p_sys ); 
    238         return VLC_EGENERIC; 
    239     } 
    240  
    241     if( p_sys->active )  
    242     { 
    243         msg_Dbg( p_access, "Activation active connection"); 
    244         if( rtmp_connect_active( p_this ) < 0) 
    245         { 
    246             msg_Err( p_access, "Active connection failed"); 
    247             vlc_UrlClean( &p_sys->url ); 
    248             net_Close( p_sys-> fd ); 
    249             free( p_sys ); 
    250             return VLC_EGENERIC; 
     237        goto error2; 
     238    } 
     239 
     240    if( p_sys->active ) 
     241    { 
     242        if( rtmp_connect_active( p_sys->p_thread ) < 0 ) 
     243        { 
     244            msg_Err( p_access, "connect active failed"); 
     245            goto error2; 
    251246        } 
    252247    } 
     
    256251    p_access->p_sys->read_packet = 1; 
    257252 
    258     msg_Dbg( p_access, "waiting for buffer to fill"); 
    259     /* Wait until enough data is received for extracting metadata */ 
    260     while( block_FifoCount( p_access->p_sys->p_thread->p_fifo_media ) < 10 ) 
    261     { 
    262         msg_Dbg( p_access, "waiting for buffer to fill"); 
    263         msleep(1000); 
    264         continue; 
    265     } 
    266  
    267253    /* Update default_pts to a suitable value for rtmp access */ 
    268254    var_Create( p_access, "rtmp-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); 
    269255 
    270256    return VLC_SUCCESS; 
     257 
     258error2: 
     259    vlc_cond_destroy( &p_sys->p_thread->wait ); 
     260    vlc_mutex_destroy( &p_sys->p_thread->lock ); 
     261 
     262    free( p_sys->p_thread->psz_application ); 
     263    free( p_sys->p_thread->psz_media ); 
     264 
     265    net_Close( p_sys->p_thread->fd ); 
     266error: 
     267    vlc_object_detach( p_sys->p_thread ); 
     268    vlc_object_release( p_sys->p_thread ); 
     269 
     270    vlc_UrlClean( &p_sys->p_thread->url ); 
     271    free( p_sys ); 
     272 
     273    return VLC_EGENERIC; 
    271274} 
    272275 
     
    278281    access_t     *p_access = (access_t *) p_this; 
    279282    access_sys_t *p_sys = p_access->p_sys; 
    280  
    281     msg_Warn(p_access, "Close"); 
    282  
     283    int i; 
     284 
     285/*    p_sys->p_thread->b_die = true;*/ 
    283286    vlc_object_kill( p_sys->p_thread ); 
    284     block_FifoWake( p_sys->p_thread->p_fifo_media ); 
     287    block_FifoWake( p_sys->p_thread->p_fifo_input ); 
    285288    block_FifoWake( p_sys->p_thread->p_empty_blocks ); 
    286     /* 
    287     for( i = 0; i < 5; i++ ) 
    288     { 
    289         block_t *p_dummy = block_New( p_access, 256 ); 
    290         p_dummy->i_dts = 0; 
    291         p_dummy->i_pts = 0; 
    292         p_dummy->i_length = 0; 
    293         memset( p_dummy->p_buffer, 0, p_dummy->i_buffer ); 
    294         block_FifoPut( p_sys->p_thread->p_fifo_media, p_dummy ); 
    295     } 
    296     for( i = 0; i < 5; i++ ) 
    297     { 
    298         block_t *p_dummy = block_New( p_access, 256 ); 
    299         p_dummy->i_dts = 0; 
    300         p_dummy->i_pts = 0; 
    301         p_dummy->i_length = 0; 
    302         memset( p_dummy->p_buffer, 0, p_dummy->i_buffer ); 
    303         block_FifoPut( p_sys->p_thread->p_empty_blocks, p_dummy ); 
    304     }*/ 
     289 
    305290    vlc_thread_join( p_sys->p_thread ); 
    306291 
     
    308293    vlc_mutex_destroy( &p_sys->p_thread->lock ); 
    309294 
    310     block_FifoRelease( p_sys->p_thread->p_fifo_media ); 
     295    block_FifoRelease( p_sys->p_thread->p_fifo_input ); 
    311296    block_FifoRelease( p_sys->p_thread->p_empty_blocks ); 
    312297 
    313     net_Close( p_sys->fd ); 
     298    for( i = 0; i < 64; i++ ) /* RTMP_HEADER_STREAM_INDEX_MASK */ 
     299    { 
     300        if( p_sys->p_thread->rtmp_headers_recv[i].body != NULL ) 
     301        { 
     302            free( p_sys->p_thread->rtmp_headers_recv[i].body->body ); 
     303            free( p_sys->p_thread->rtmp_headers_recv[i].body ); 
     304        } 
     305    } 
     306 
     307    net_Close( p_sys->p_thread->fd ); 
    314308 
    315309    var_Destroy( p_access, "rtmp-caching" ); 
    316310 
    317  
    318     vlc_UrlClean( &p_sys->url ); 
    319     free( p_sys->psz_application ); 
    320     free( p_sys->psz_media ); 
     311    vlc_object_detach( p_sys->p_thread ); 
     312    vlc_object_release( p_sys->p_thread ); 
     313 
     314    vlc_UrlClean( &p_sys->p_thread->url ); 
     315    free( p_sys->p_thread->psz_application ); 
     316    free( p_sys->p_thread->psz_media ); 
    321317    free( p_sys ); 
    322318} 
     
    328324{ 
    329325    access_sys_t *p_sys = p_access->p_sys; 
     326    rtmp_packet_t *rtmp_packet; 
     327    uint8_t *tmp_buffer; 
     328    ssize_t i_ret; 
    330329    int i_len_tmp; 
    331330 
    332     if( p_sys->fd < 0 ) 
    333     { 
    334         p_access->info.b_eof = true; 
    335         return 0; 
    336     } 
    337  
    338331    i_len_tmp = 0; 
    339332 
    340333    while( i_len_tmp < i_len ) 
    341334    { 
     335        if( p_sys->p_thread->result_stop || p_access->info.b_eof || p_access->b_die ) 
     336        { 
     337            p_access->info.b_eof = true; 
     338            return 0; 
     339        } 
     340 
    342341        if( p_sys->read_packet ) 
    343342        { 
    344343            if( !p_sys->p_thread->metadata_received ) 
    345344            { 
     345                /* Wait until enough data is received for extracting metadata */ 
     346                if( block_FifoCount( p_sys->p_thread->p_fifo_input ) < 10 ) 
     347                { 
     348                    msleep(100000); 
     349                    continue; 
     350                } 
     351 
    346352                p_sys->flv_packet = flv_get_metadata( p_access ); 
    347353 
     
    350356            else 
    351357            { 
    352                 if( p_sys->active && block_FifoCount( p_sys->p_thread->p_fifo_media ) == 0 ) 
    353                 { 
    354                     p_access->info.b_eof = true; 
    355                     break; 
    356                 } 
    357  
    358                 p_sys->flv_packet = block_FifoGet( p_sys->p_thread->p_fifo_media ); 
     358                p_sys->flv_packet = block_FifoGet( p_sys->p_thread->p_fifo_input ); 
    359359                if( p_sys->flv_packet == NULL ) 
    360360                    continue; /* Forced wake-up */ 
     
    401401            p_sys->p_thread->result_publish = 0; 
    402402 
    403             rtmp_send_publish_start( p_access ); 
     403            rtmp_packet = rtmp_build_publish_start( p_sys->p_thread ); 
     404 
     405            tmp_buffer = rtmp_encode_packet( p_sys->p_thread, rtmp_packet ); 
     406 
     407            i_ret = net_Write( p_sys->p_thread, p_sys->p_thread->fd, NULL, tmp_buffer, rtmp_packet->length_encoded ); 
     408            if( i_ret != rtmp_packet->length_encoded ) 
     409            { 
     410                free( rtmp_packet->body->body ); 
     411                free( rtmp_packet->body ); 
     412                free( rtmp_packet ); 
     413                free( tmp_buffer ); 
     414                msg_Err( p_access, "failed send publish start" ); 
     415            } 
     416            free( rtmp_packet->body->body ); 
     417            free( rtmp_packet->body ); 
     418            free( rtmp_packet ); 
     419            free( tmp_buffer ); 
    404420        } 
    405421 
    406422        p_access->info.i_pos += i_len_tmp; 
    407423 
    408         rtmp_send_bytes_read( p_access, p_access->info.i_pos ); 
     424        rtmp_packet = rtmp_build_bytes_read( p_sys->p_thread, p_access->info.i_pos ); 
     425 
     426        tmp_buffer = rtmp_encode_packet( p_sys->p_thread, rtmp_packet ); 
     427  
     428        i_ret = net_Write( p_sys->p_thread, p_sys->p_thread->fd, NULL, tmp_buffer, rtmp_packet->length_encoded ); 
     429        if( i_ret != rtmp_packet->length_encoded ) 
     430        { 
     431            free( rtmp_packet->body->body ); 
     432            free( rtmp_packet->body ); 
     433            free( rtmp_packet ); 
     434            free( tmp_buffer ); 
     435            msg_Err( p_access, "failed send bytes read" ); 
     436        } 
     437        free( rtmp_packet->body->body ); 
     438        free( rtmp_packet->body ); 
     439        free( rtmp_packet ); 
     440        free( tmp_buffer ); 
    409441    } 
    410442 
     
    437469static int Control( access_t *p_access, int i_query, va_list args ) 
    438470{ 
    439     bool   *pb_bool; 
    440     int          *pi_int; 
    441     int64_t      *pi_64; 
     471    bool    *pb_bool; 
     472    int     *pi_int; 
     473    int64_t *pi_64; 
    442474 
    443475    switch( i_query ) 
     
    446478        case ACCESS_CAN_SEEK: 
    447479        case ACCESS_CAN_FASTSEEK: 
    448             pb_bool = (bool*)va_arg( args, bool* ); 
     480            pb_bool = (bool*) va_arg( args, bool* ); 
    449481            *pb_bool = false; /* TODO */ 
    450482            break; 
    451483 
    452484        case ACCESS_CAN_PAUSE: 
    453             pb_bool = (bool*)va_arg( args, bool* ); 
     485            pb_bool = (bool*) va_arg( args, bool* ); 
    454486            *pb_bool = false; /* TODO */ 
    455487            break; 
    456488 
    457489        case ACCESS_CAN_CONTROL_PACE: 
    458             pb_bool = (bool*)va_arg( args, bool* ); 
     490            pb_bool = (bool*) va_arg( args, bool* ); 
    459491            *pb_bool = true; 
    460492            break; 
     
    462494        /* */ 
    463495        case ACCESS_GET_MTU: 
    464             pi_int = (int*)va_arg( args, int * ); 
     496            pi_int = (int*) va_arg( args, int * ); 
    465497            *pi_int = 0; 
    466498            break; 
    467499 
    468500        case ACCESS_GET_PTS_DELAY: 
    469             pi_64 = (int64_t*)va_arg( args, int64_t * ); 
     501            pi_64 = (int64_t*) va_arg( args, int64_t * ); 
    470502            *pi_64 = var_GetInteger( p_access, "rtmp-caching" ) * INT64_C(1000); 
    471503            break; 
     
    504536    while( !p_thread->b_die ) 
    505537    { 
    506  
    507538        rtmp_packet = rtmp_read_net_packet( p_thread ); 
    508539        if( rtmp_packet != NULL ) 
     
    510541            if( rtmp_packet->content_type < 0x01 /* RTMP_CONTENT_TYPE_CHUNK_SIZE */ 
    511542                || rtmp_packet->content_type > 0x14 ) /* RTMP_CONTENT_TYPE_INVOKE */ 
     543            { 
     544                free( rtmp_packet->body->body ); 
     545                free( rtmp_packet->body ); 
     546                free( rtmp_packet ); 
     547 
    512548                msg_Warn( p_thread, "unknown content type received" ); 
     549            } 
    513550            else 
    514551                p_thread->rtmp_handler[rtmp_packet->content_type]( p_thread, rtmp_packet ); 
     
    525562 
    526563            p_thread->b_die = 1; 
     564            ((access_t *) p_thread->p_base_object)->info.b_eof = true; 
     565 
     566            block_FifoWake( p_thread->p_fifo_input ); 
    527567        } 
    528568    } 
  • modules/access/rtmp/rtmp_amf_flv.c

    r449fd28 raa5fe86  
    9999const uint8_t RTMP_PING_SIZE_CLEAR_PLAYING_BUFFER = 6; 
    100100const uint8_t RTMP_PING_SIZE_BUFFER_TIME_CLIENT = 10; 
    101 /*const uint8_t RTMP_PING_SIZE_RESET_STREAM = 0x0004; TODO 
    102 const uint8_t RTMP_PING_SIZE_CLIENT_FROM_SERVER = 0x0006; 
     101const uint8_t RTMP_PING_SIZE_RESET_STREAM = 6; 
     102/*const uint8_t RTMP_PING_SIZE_CLIENT_FROM_SERVER = 0x0006; TODO 
    103103const uint8_t RTMP_PING_SIZE_PONG_FROM_CLIENT = 0x0007; 
    104104*/ 
    105105 
     106/* default values */ 
     107const uint8_t RTMP_DEFAULT_STREAM_INDEX_CONTROL = 0x02; 
     108const uint8_t RTMP_DEFAULT_STREAM_INDEX_INVOKE = 0x03; 
     109const uint8_t RTMP_DEFAULT_STREAM_INDEX_NOTIFY = 0x04; 
     110const uint8_t RTMP_DEFAULT_STREAM_INDEX_VIDEO_DATA = 0x05; 
     111const uint8_t RTMP_DEFAULT_STREAM_INDEX_AUDIO_DATA = 0x06; 
     112const uint32_t RTMP_DEFAULT_CHUNK_SIZE = 128; 
     113const double RTMP_DEFAULT_STREAM_CLIENT_ID = 1.0; 
     114const double RTMP_DEFAULT_STREAM_SERVER_ID = 1.0; 
     115 
    106116/* misc */ 
    107 const uint16_t MAX_EMPTY_BLOCKS = 200; /* empty_blocks in fifo for media*/ 
     117const uint16_t MAX_EMPTY_BLOCKS = 200; /* empty blocks in fifo for media*/ 
    108118const uint16_t RTMP_BODY_SIZE_ALLOC = 1024; 
    109 const uint32_t RTMP_TIME_CLIENT_BUFFER = 5000; /* miliseconds */ 
    110 const uint8_t RTMP_CONTROL_STREAM_INDEX_DEFAULT = 0x02; 
    111 const uint8_t RTMP_AMF_STREAM_INDEX_DEFAULT = 0x03; 
     119const uint32_t RTMP_TIME_CLIENT_BUFFER = 2000; /* miliseconds */ 
     120const uint32_t RTMP_SERVER_BW = 0x00000200; 
    112121const uint32_t RTMP_SRC_DST_CONNECT_OBJECT = 0x00000000; 
    113122const uint32_t RTMP_SRC_DST_CONNECT_OBJECT2 = 0x00000001; 
     
    116125const uint64_t RTMP_VIDEOCODECS = 0x405f000000000000; 
    117126const uint64_t RTMP_VIDEOFUNCTION = 0x3ff0000000000000; 
    118  
    119127/***************************************************************************** 
    120128 * AMF header: 
    121129 ******************************************************************************/ 
    122  
    123 /* packet sizes */ 
    124 const uint8_t AMF_PACKET_SIZE_VIDEO = 128; 
    125 const uint8_t AMF_PACKET_SIZE_AUDIO = 64; 
    126130 
    127131/* boolean constants */ 
     
    166170const uint64_t AMF_CALL_NETCONNECTION_CONNECT_OBJECTENCODING = 0x0; 
    167171const double AMF_CALL_STREAM_CLIENT_NUMBER = 3.0; 
     172const double AMF_CALL_ONBWDONE = 2.0;  
    168173const uint64_t AMF_CALL_NETSTREAM_PLAY = 0x0; 
    169174 
     
    222227 * static RTMP functions: 
    223228 ******************************************************************************/ 
    224 static void rtmp_handler_null       ( rtmp_control_thread_t *rtmp_control_thread, rtmp_packet_t *rtmp_packet ); 
    225 static void rtmp_handler_invoke     ( rtmp_control_thread_t *rtmp_control_thread, rtmp_packet_t *rtmp_packet ); 
    226 static void rtmp_handler_audio_data ( rtmp_control_thread_t *rtmp_control_thread, rtmp_packet_t *rtmp_packet ); 
    227 static void rtmp_handler_video_data ( rtmp_control_thread_t *rtmp_control_thread, rtmp_packet_t *rtmp_packet ); 
    228 static void rtmp_handler_notify     ( rtmp_control_thread_t *rtmp_control_thread, rtmp_packet_t *rtmp_packet ); 
     229static void rtmp_handler_null       ( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet ); 
     230static void rtmp_handler_chunk_size ( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet ); 
     231static void rtmp_handler_invoke     ( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet ); 
     232static void rtmp_handler_audio_data ( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet ); 
     233static void rtmp_handler_video_data ( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet ); 
     234static void rtmp_handler_notify     ( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet ); 
    229235 
    230236static rtmp_packet_t *rtmp_new_packet( rtmp_control_thread_t *p_thread, uint8_t stream_index, uint32_t timestamp, uint8_t content_type, uint32_t src_dst, rtmp_body_t *body ); 
    231  
    232 static uint8_t *rtmp_encode_packet( access_t *p_access, rtmp_packet_t *rtmp_packet ); 
    233 static rtmp_packet_t *rtmp_encode_NetConnection_Connect_result( rtmp_control_thread_t *p_thread, double number ); 
    234 static rtmp_packet_t *rtmp_encode_createStream_result( rtmp_control_thread_t *p_thread, double number ); 
    235 static uint8_t rtmp_encode_header_size( access_t *p_access, uint8_t header_size ); 
     237static block_t *rtmp_new_block( rtmp_control_thread_t *p_thread, uint8_t *buffer, int32_t length_buffer ); 
     238 
     239static rtmp_packet_t *rtmp_encode_onBWDone( rtmp_control_thread_t *p_thread, double number ); 
     240static rtmp_packet_t *rtmp_encode_server_bw( rtmp_control_thread_t *p_thread, uint32_t number ); 
     241static rtmp_packet_t *rtmp_encode_NetConnection_connect_result( rtmp_control_thread_t *p_thread, double number ); 
     242static rtmp_packet_t *rtmp_encode_createStream_result( rtmp_control_thread_t *p_thread, double stream_client, double stream_server ); 
     243static rtmp_packet_t *rtmp_encode_ping_reset_stream( rtmp_control_thread_t *p_thread ); 
     244static rtmp_packet_t *rtmp_encode_ping_clear_stream( rtmp_control_thread_t *p_thread, uint32_t src_dst ); 
     245static rtmp_packet_t *rtmp_encode_NetStream_play_reset_onStatus( rtmp_control_thread_t *p_thread, char *psz_media ); 
     246static rtmp_packet_t *rtmp_encode_NetStream_play_start_onStatus( rtmp_control_thread_t *p_thread, char *psz_media ); 
     247static uint8_t rtmp_encode_header_size( vlc_object_t *p_this, uint8_t header_size ); 
    236248static uint8_t rtmp_decode_header_size( vlc_object_t *p_this, uint8_t header_size ); 
    237  
    238 static rtmp_body_t *rtmp_body_new( void ); 
    239 static void rtmp_body_append( rtmp_body_t *rtmp_body, uint8_t *buffer, uint8_t length ); 
    240  
    241 static uint8_t *ping_encode( uint16_t type, uint32_t src_dst, uint32_t third_arg, uint32_t fourth_arg );/*TODO: change function name*/ 
     249static uint8_t rtmp_get_stream_index( uint8_t content_type ); 
     250 
     251static void rtmp_body_append( rtmp_body_t *rtmp_body, uint8_t *buffer, uint32_t length ); 
     252 
     253static uint8_t *rtmp_encode_ping( uint16_t type, uint32_t src_dst, uint32_t third_arg, uint32_t fourth_arg ); 
    242254 
    243255/***************************************************************************** 
     
    254266 * static FLV functions: 
    255267 ******************************************************************************/ 
    256 static block_t *flv_new_packet( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet ); 
    257 static void flv_rebuild( rtmp_control_thread_t *rtmp_control_thread, rtmp_packet_t *rtmp_packet ); 
    258 static void flv_get_metadata_audio( rtmp_packet_t *packet_audio, uint8_t *stereo, uint8_t *audiosamplesize, uint8_t *audiosamplerate, uint8_t *audiocodecid ); 
    259 static void flv_get_metadata_video( rtmp_packet_t *packet_video, uint8_t *videocodecid, uint8_t *frametype ); 
    260 static rtmp_packet_t *flv_build_onMetaData( access_t *p_access, uint64_t duration, uint8_t stereo, uint8_t audiosamplesize, uint8_t audiosamplerate, uint8_t audiocodecid, uint8_t videocodecid ); 
     268static void flv_rebuild( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet ); 
     269static void flv_get_metadata_audio( rtmp_control_thread_t *p_thread, rtmp_packet_t *packet_audio, uint8_t *stereo, uint8_t *audiosamplesize, uint32_t *audiosamplerate, uint8_t *audiocodecid ); 
     270static void flv_get_metadata_video( rtmp_control_thread_t *p_thread, rtmp_packet_t *packet_video, uint8_t *videocodecid, uint8_t *frametype ); 
     271static rtmp_packet_t *flv_build_onMetaData( access_t *p_access, uint64_t duration, uint8_t stereo, uint8_t audiosamplesize, uint32_t audiosamplerate, uint8_t audiocodecid, uint8_t videocodecid ); 
    261272 
    262273/***************************************************************************** 
    263274 * RTMP implementation: 
    264275 ******************************************************************************/ 
    265  
    266 /***************************************************************************** 
    267  * rtmp_handshake_passive: 
    268  *******************************************************************************/ 
    269 int rtmp_handshake_passive( vlc_object_t *p_this ) 
    270 
    271     access_t     *p_access = (access_t *) p_this; 
    272     access_sys_t *p_sys = p_access->p_sys; 
     276int 
     277rtmp_handshake_passive( vlc_object_t *p_this, int fd ) 
     278
    273279    uint8_t p_read[RTMP_HANDSHAKE_BODY_SIZE + 1]; 
    274280    uint8_t p_write[RTMP_HANDSHAKE_BODY_SIZE * 2 + 1]; 
     
    277283 
    278284    /* Receive handshake */ 
    279     i_ret = net_Read( p_access, p_sys->fd, NULL, p_read, RTMP_HANDSHAKE_BODY_SIZE + 1, true ); 
     285    i_ret = net_Read( p_this, fd, NULL, p_read, RTMP_HANDSHAKE_BODY_SIZE + 1, true ); 
    280286    if( i_ret != RTMP_HANDSHAKE_BODY_SIZE + 1 ) 
    281287    { 
    282         msg_Err( p_access, "failed to receive handshake" ); 
     288        msg_Err( p_this, "failed to receive handshake" ); 
    283289        return -1; 
    284290    } 
     
    287293    if ( p_read[0] != RTMP_HANDSHAKE ) 
    288294    { 
    289         msg_Err( p_access, "first byte in handshake corrupt" ); 
     295        msg_Err( p_this, "first byte in handshake corrupt" ); 
    290296        return -1; 
    291297    } 
     
    297303 
    298304    /* Send handshake*/ 
    299     i_ret = net_Write( p_access, p_sys->fd, NULL, p_write, RTMP_HANDSHAKE_BODY_SIZE * 2 + 1 ); 
     305    i_ret = net_Write( p_this, fd, NULL, p_write, RTMP_HANDSHAKE_BODY_SIZE * 2 + 1 ); 
    300306    if( i_ret != RTMP_HANDSHAKE_BODY_SIZE * 2 + 1 ) 
    301307    { 
    302         msg_Err( p_access, "failed to send handshake" ); 
     308        msg_Err( p_this, "failed to send handshake" ); 
    303309        return -1; 
    304310    } 
    305311 
    306312    /* Receive acknowledge */ 
    307     i_ret = net_Read( p_access, p_sys->fd, NULL, p_read, RTMP_HANDSHAKE_BODY_SIZE, true ); 
     313    i_ret = net_Read( p_this, fd, NULL, p_read, RTMP_HANDSHAKE_BODY_SIZE, true ); 
    308314    if( i_ret != RTMP_HANDSHAKE_BODY_SIZE ) 
    309315    { 
    310         msg_Err( p_access, "failed to receive acknowledge" ); 
     316        msg_Err( p_this, "failed to receive acknowledge" ); 
    311317        return -1; 
    312318    } 
     
    316322        if( p_write[i + 1] != p_read[i] ) 
    317323        { 
    318             msg_Err( p_access, "body acknowledge received corrupt" ); 
     324            msg_Err( p_this, "body acknowledge received corrupt" ); 
    319325            return -1; 
    320326        } 
     
    322328    return 0; 
    323329} 
    324 /***************************************************************************** 
    325  * rtmp_handshake_active: 
    326  *******************************************************************************/ 
    327 int rtmp_handshake_active( vlc_object_t *p_this ) 
    328 
    329     access_t     *p_access = (access_t *) p_this; 
    330     access_sys_t *p_sys = p_access->p_sys; 
     330 
     331int 
     332rtmp_handshake_active( vlc_object_t *p_this, int fd ) 
     333
    331334    uint8_t p_read[RTMP_HANDSHAKE_BODY_SIZE * 2 + 1]; 
    332335    uint8_t p_write[RTMP_HANDSHAKE_BODY_SIZE + 1]; 
     
    339342 
    340343    /* Send handshake*/ 
    341     i_ret = net_Write( p_access, p_sys->fd, NULL, p_write, RTMP_HANDSHAKE_BODY_SIZE + 1 ); 
     344    i_ret = net_Write( p_this, fd, NULL, p_write, RTMP_HANDSHAKE_BODY_SIZE + 1 ); 
    342345    if( i_ret != RTMP_HANDSHAKE_BODY_SIZE + 1 ) 
    343346    { 
    344         msg_Err( p_access, "failed to send handshake" ); 
     347        msg_Err( p_this, "failed to send handshake" ); 
    345348        return -1; 
    346349    } 
    347350 
    348351    /* Receive handshake */ 
    349     i_ret = net_Read( p_access, p_sys->fd, NULL, p_read, RTMP_HANDSHAKE_BODY_SIZE * 2 + 1, true ); 
     352    i_ret = net_Read( p_this, fd, NULL, p_read, RTMP_HANDSHAKE_BODY_SIZE * 2 + 1, true ); 
    350353    if( i_ret != RTMP_HANDSHAKE_BODY_SIZE * 2 + 1 ) 
    351354    { 
    352         msg_Err( p_access, "failed to receive handshake" ); 
     355        msg_Err( p_this, "failed to receive handshake" ); 
    353356        return -1; 
    354357    } 
     
    357360    if( p_read[0] != RTMP_HANDSHAKE ) 
    358361    { 
    359         msg_Err( p_access, "first byte in handshake received corrupt" ); 
     362        msg_Err( p_this, "first byte in handshake received corrupt" ); 
    360363        return -1; 
    361364    } 
    362365 
    363     for(i = 0; i < RTMP_HANDSHAKE_BODY_SIZE; i++ ) 
     366    for(i = 8; i < RTMP_HANDSHAKE_BODY_SIZE; i++ ) 
    364367        if( p_write[i + 1] != p_read[i + 1 + RTMP_HANDSHAKE_BODY_SIZE] ) 
    365368        { 
    366             msg_Err( p_access, "body handshake received corrupt" ); 
     369            msg_Err( p_this, "body handshake received corrupt" ); 
    367370            return -1; 
    368371        } 
    369372 
    370373    /* Acknowledge handshake */ 
    371     i_ret = net_Write( p_access, p_sys->fd, NULL, p_read + 1, RTMP_HANDSHAKE_BODY_SIZE ); 
     374    i_ret = net_Write( p_this, fd, NULL, p_read + 1, RTMP_HANDSHAKE_BODY_SIZE ); 
    372375    if( i_ret != RTMP_HANDSHAKE_BODY_SIZE ) 
    373376    { 
    374         msg_Err( p_access, "failed to acknowledge handshake" ); 
     377        msg_Err( p_this, "failed to acknowledge handshake" ); 
    375378        return -1; 
    376379    } 
     
    379382} 
    380383 
    381 /***************************************************************************** 
    382  * rtmp_connect_active: 
    383  ******************************************************************************/ 
    384 int rtmp_connect_active( vlc_object_t *p_this ) 
    385 
    386     access_t     *p_access = (access_t *) p_this; 
    387     access_sys_t *p_sys = p_access->p_sys; 
     384int 
     385rtmp_connect_active( rtmp_control_thread_t *p_thread ) 
     386
    388387    rtmp_packet_t *rtmp_packet; 
    389388    rtmp_body_t *rtmp_body; 
     
    393392 
    394393    /* Build NetConnection.connect call */ 
    395     rtmp_body = rtmp_body_new(); 
     394    rtmp_body = rtmp_body_new( -1 ); 
    396395 
    397396    tmp_buffer = amf_encode_element( AMF_DATATYPE_STRING, "connect" ); 
     
    410409 
    411410    tmp_buffer = amf_encode_object_variable( "app", 
    412         AMF_DATATYPE_STRING, p_sys->psz_application ); 
     411        AMF_DATATYPE_STRING, p_thread->psz_application ); 
    413412    rtmp_body_append( rtmp_body, tmp_buffer, 
    414413        AMF_DATATYPE_SIZE_OBJECT_VARIABLE + strlen( "app" ) +  
    415         AMF_DATATYPE_SIZE_STRING + strlen( p_sys->psz_application ) ); 
    416     free ( tmp_buffer ); 
     414        AMF_DATATYPE_SIZE_STRING + strlen( p_thread->psz_application ) ); 
     415    free( tmp_buffer ); 
    417416 
    418417    tmp_buffer = amf_encode_object_variable( "flashVer", 
     
    421420        AMF_DATATYPE_SIZE_OBJECT_VARIABLE + strlen( "flashVer" ) + 
    422421        AMF_DATATYPE_SIZE_STRING + strlen( "LNX 9,0,48,0" ) ); 
    423     free ( tmp_buffer ); 
     422    free( tmp_buffer ); 
    424423 
    425424    tmp_buffer = amf_encode_object_variable( "swfUrl", 
     
    428427        AMF_DATATYPE_SIZE_OBJECT_VARIABLE + strlen( "swfUrl" ) + 
    429428        AMF_DATATYPE_SIZE_STRING + strlen( "file:///mac.flv" ) ); 
    430     free ( tmp_buffer ); 
    431  
    432     tmp_url = (char *) malloc( strlen( "rtmp://") + strlen( p_sys->url.psz_buffer ) + 1 ); 
    433     sprintf( tmp_url, "rtmp://%s", p_sys->url.psz_buffer ); 
     429    free( tmp_buffer ); 
     430 
     431    tmp_url = (char *) malloc( strlen( "rtmp://") + strlen( p_thread->url.psz_buffer ) + 1 ); 
     432    sprintf( tmp_url, "rtmp://%s", p_thread->url.psz_buffer ); 
    434433    tmp_buffer = amf_encode_object_variable( "tcUrl", 
    435434        AMF_DATATYPE_STRING, tmp_url ); 
     
    486485    free( tmp_buffer ); 
    487486 
    488     rtmp_packet = rtmp_new_packet( p_sys->p_thread, RTMP_AMF_STREAM_INDEX_DEFAULT
     487    rtmp_packet = rtmp_new_packet( p_thread, RTMP_DEFAULT_STREAM_INDEX_INVOKE
    489488        0, RTMP_CONTENT_TYPE_INVOKE, 0, rtmp_body ); 
    490489    free( rtmp_body->body ); 
    491490    free( rtmp_body ); 
    492491 
    493     tmp_buffer = rtmp_encode_packet( p_access, rtmp_packet ); 
     492    tmp_buffer = rtmp_encode_packet( p_thread, rtmp_packet ); 
    494493 
    495494    /* Call NetConnection.connect */ 
    496     i_ret = net_Write( p_access, p_sys->fd, NULL, tmp_buffer, rtmp_packet->length_encoded ); 
     495    i_ret = net_Write( p_thread, p_thread->fd, NULL, tmp_buffer, rtmp_packet->length_encoded ); 
    497496    if( i_ret != rtmp_packet->length_encoded ) 
    498497    { 
     
    501500        free( rtmp_packet ); 
    502501        free( tmp_buffer ); 
    503         msg_Err( p_access, "failed send call NetConnection.connect" ); 
     502        msg_Err( p_thread, "failed send call NetConnection.connect" ); 
    504503        return -1; 
    505504    } 
     
    510509 
    511510    /* Wait for NetConnection.connect result */ 
    512     vlc_mutex_lock( &p_sys->p_thread->lock ); 
    513     vlc_cond_wait( &p_sys->p_thread->wait, &p_sys->p_thread->lock ); 
    514     vlc_mutex_unlock( &p_sys->p_thread->lock ); 
    515  
    516     if( p_sys->p_thread->result_connect ) 
    517     { 
    518         msg_Err( p_access, "failed call NetConnection.connect" ); 
     511    vlc_mutex_lock( &p_thread->lock ); 
     512    vlc_cond_wait( &p_thread->wait, &p_thread->lock ); 
     513    vlc_mutex_unlock( &p_thread->lock ); 
     514 
     515    if( p_thread->result_connect ) 
     516    { 
     517        msg_Err( p_thread, "failed call NetConnection.connect" ); 
    519518        return -1; 
    520519    } 
    521520 
    522521    /* Force control thread to stop if receive NetStream.play call and wait is not ready */ 
    523     vlc_mutex_lock( &p_sys->p_thread->lock ); 
     522    vlc_mutex_lock( &p_thread->lock ); 
    524523 
    525524    /* Build NetStream.createStream call */ 
    526     rtmp_body = rtmp_body_new(); 
     525    rtmp_body = rtmp_body_new( -1 ); 
    527526 
    528527    tmp_buffer = amf_encode_element( AMF_DATATYPE_STRING, "createStream" ); 
     
    531530    free( tmp_buffer ); 
    532531 
    533     p_sys->p_thread->stream_client = AMF_CALL_STREAM_CLIENT_NUMBER
     532    p_thread->stream_client_id = RTMP_DEFAULT_STREAM_CLIENT_ID
    534533 
    535534    tmp_buffer = amf_encode_element( AMF_DATATYPE_NUMBER, 
     
    542541    free( tmp_buffer ); 
    543542 
    544     rtmp_packet = rtmp_new_packet( p_sys->p_thread, RTMP_AMF_STREAM_INDEX_DEFAULT,  
     543    rtmp_packet = rtmp_new_packet( p_thread, RTMP_DEFAULT_STREAM_INDEX_INVOKE,  
    545544        0, RTMP_CONTENT_TYPE_INVOKE, 0, rtmp_body ); 
    546545    free( rtmp_body->body ); 
    547546    free( rtmp_body ); 
    548547 
    549     tmp_buffer = rtmp_encode_packet( p_access, rtmp_packet ); 
     548    tmp_buffer = rtmp_encode_packet( p_thread, rtmp_packet ); 
    550549 
    551550    /* Call NetStream.createStream */ 
    552     i_ret = net_Write( p_access, p_sys->fd, NULL, tmp_buffer, rtmp_packet->length_encoded ); 
     551    i_ret = net_Write( p_thread, p_thread->fd, NULL, tmp_buffer, rtmp_packet->length_encoded ); 
    553552    if( i_ret != rtmp_packet->length_encoded ) 
    554553    { 
     
    557556        free( rtmp_packet ); 
    558557        free( tmp_buffer ); 
    559         msg_Err( p_access, "failed send call NetStream.createStream" ); 
     558        msg_Err( p_thread, "failed send call NetStream.createStream" ); 
    560559        return -1; 
    561560    } 
     
    566565/*TODO: read server stream number*/ 
    567566    /* Build ping packet */ 
    568     rtmp_body = rtmp_body_new(); 
    569  
    570     tmp_buffer = ping_encode( RTMP_PING_BUFFER_TIME_CLIENT, RTMP_SRC_DST_CONNECT_OBJECT, RTMP_TIME_CLIENT_BUFFER, 0 ); 
     567    rtmp_body = rtmp_body_new( -1 ); 
     568 
     569    tmp_buffer = rtmp_encode_ping( RTMP_PING_BUFFER_TIME_CLIENT, RTMP_SRC_DST_CONNECT_OBJECT, RTMP_TIME_CLIENT_BUFFER, 0 ); 
    571570    rtmp_body_append( rtmp_body, tmp_buffer, RTMP_PING_SIZE_BUFFER_TIME_CLIENT ); 
    572571    free( tmp_buffer ); 
    573572 
    574     rtmp_packet = rtmp_new_packet( p_sys->p_thread, RTMP_CONTROL_STREAM_INDEX_DEFAULT
     573    rtmp_packet = rtmp_new_packet( p_thread, RTMP_DEFAULT_STREAM_INDEX_CONTROL
    575574        0, RTMP_CONTENT_TYPE_PING, 0, rtmp_body ); 
    576575    free( rtmp_body->body ); 
    577576    free( rtmp_body ); 
    578577 
    579     tmp_buffer = rtmp_encode_packet( p_access, rtmp_packet ); 
     578    tmp_buffer = rtmp_encode_packet( p_thread, rtmp_packet ); 
    580579 
    581580    /* Send ping packet */ 
    582     i_ret = net_Write( p_access, p_sys->fd, NULL, tmp_buffer, rtmp_packet->length_encoded ); 
     581    i_ret = net_Write( p_thread, p_thread->fd, NULL, tmp_buffer, rtmp_packet->length_encoded ); 
    583582    if( i_ret != rtmp_packet->length_encoded ) 
    584583    { 
     
    587586        free( rtmp_packet ); 
    588587        free( tmp_buffer ); 
    589         msg_Err( p_access, "failed send ping BUFFER_TIME_CLIENT" ); 
     588        msg_Err( p_thread, "failed send ping BUFFER_TIME_CLIENT" ); 
    590589        return -1; 
    591590    } 
     
    596595 
    597596    /* Build NetStream.play call */ 
    598     rtmp_body = rtmp_body_new(); 
     597    rtmp_body = rtmp_body_new( -1 ); 
    599598 
    600599    tmp_buffer = amf_encode_element( AMF_DATATYPE_STRING, "play" ); 
     
    612611    free( tmp_buffer ); 
    613612 
    614     tmp_buffer = amf_encode_element( AMF_DATATYPE_STRING, p_sys->psz_media ); 
    615     rtmp_body_append( rtmp_body, tmp_buffer, 
    616         AMF_DATATYPE_SIZE_STRING + strlen( p_sys->psz_media ) ); 
    617     free( tmp_buffer ); 
    618  
    619     rtmp_packet = rtmp_new_packet( p_sys->p_thread, RTMP_AMF_STREAM_INDEX_DEFAULT
     613    tmp_buffer = amf_encode_element( AMF_DATATYPE_STRING, p_thread->psz_media ); 
     614    rtmp_body_append( rtmp_body, tmp_buffer, 
     615        AMF_DATATYPE_SIZE_STRING + strlen( p_thread->psz_media ) ); 
     616    free( tmp_buffer ); 
     617 
     618