| 
																	
																	
																		
																	
																	
																 | 
																@@ -1021,12 +1021,88 @@ static int handle_server_bw(URLContext *s, RTMPPacket *pkt) | 
															
														
														
													
														
															
																 | 
																 | 
																    return 0; | 
																 | 
																 | 
																    return 0; | 
															
														
														
													
														
															
																 | 
																 | 
																} | 
																 | 
																 | 
																} | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																static int handle_invoke_result(URLContext *s, RTMPPacket *pkt) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																{ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    RTMPContext *rt = s->priv_data; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    char *tracked_method = NULL; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    GetByteContext gbc; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    double pkt_id; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    int ret = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    int i; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    bytestream2_init(&gbc, pkt->data + 10, pkt->data_size); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return ret; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    for (i = 0; i < rt->nb_tracked_methods; i++) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (rt->tracked_methods[i].id != pkt_id) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            continue; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        tracked_method = rt->tracked_methods[i].name; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        del_tracked_method(rt, i); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        break; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    if (!tracked_method) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        /* Ignore this reply when the current method is not tracked. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return ret; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    if (!memcmp(tracked_method, "connect", 7)) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (!rt->is_input) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            if ((ret = gen_release_stream(s, rt)) < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                goto fail; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            if ((ret = gen_fcpublish_stream(s, rt)) < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                goto fail; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        } else { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            if ((ret = gen_server_bw(s, rt)) < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                goto fail; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if ((ret = gen_create_stream(s, rt)) < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            goto fail; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (rt->is_input) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            /* Send the FCSubscribe command when the name of live | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																             * stream is defined by the user or if it's a live stream. */ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            if (rt->subscribe) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                if ((ret = gen_fcsubscribe_stream(s, rt, rt->subscribe)) < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                    goto fail; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            } else if (rt->live == -1) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                if ((ret = gen_fcsubscribe_stream(s, rt, rt->playpath)) < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                    goto fail; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } else if (!memcmp(tracked_method, "createStream", 12)) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        //extract a number from the result | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n"); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        } else { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            rt->main_channel_id = av_int2double(AV_RB64(pkt->data + 21)); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (!rt->is_input) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            if ((ret = gen_publish(s, rt)) < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                goto fail; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        } else { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            if ((ret = gen_play(s, rt)) < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                goto fail; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            if ((ret = gen_buffer_time(s, rt)) < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                goto fail; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																fail: | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    av_free(tracked_method); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    return ret; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																static int handle_invoke(URLContext *s, RTMPPacket *pkt) | 
																 | 
																 | 
																static int handle_invoke(URLContext *s, RTMPPacket *pkt) | 
															
														
														
													
														
															
																 | 
																 | 
																{ | 
																 | 
																 | 
																{ | 
															
														
														
													
														
															
																 | 
																 | 
																    RTMPContext *rt = s->priv_data; | 
																 | 
																 | 
																    RTMPContext *rt = s->priv_data; | 
															
														
														
													
														
															
																 | 
																 | 
																    int i, t; | 
																 | 
																 | 
																    int i, t; | 
															
														
														
													
														
															
																 | 
																 | 
																    const uint8_t *data_end = pkt->data + pkt->data_size; | 
																 | 
																 | 
																    const uint8_t *data_end = pkt->data + pkt->data_size; | 
															
														
														
													
														
															
																 | 
																 | 
																    char *tracked_method = NULL; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    int ret = 0; | 
																 | 
																 | 
																    int ret = 0; | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    //TODO: check for the messages sent for wrong state? | 
																 | 
																 | 
																    //TODO: check for the messages sent for wrong state? | 
															
														
														
													
												
													
														
															
																| 
																	
																	
																	
																		
																	
																 | 
																@@ -1038,73 +1114,8 @@ static int handle_invoke(URLContext *s, RTMPPacket *pkt) | 
															
														
														
													
														
															
																 | 
																 | 
																            av_log(s, AV_LOG_ERROR, "Server error: %s\n",tmpstr); | 
																 | 
																 | 
																            av_log(s, AV_LOG_ERROR, "Server error: %s\n",tmpstr); | 
															
														
														
													
														
															
																 | 
																 | 
																        return -1; | 
																 | 
																 | 
																        return -1; | 
															
														
														
													
														
															
																 | 
																 | 
																    } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) { | 
																 | 
																 | 
																    } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) { | 
															
														
														
													
														
															
																 | 
																 | 
																        GetByteContext gbc; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        double pkt_id; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        bytestream2_init(&gbc, pkt->data + 10, pkt->data_size); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if ((ret = handle_invoke_result(s, pkt)) < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																            return ret; | 
																 | 
																 | 
																            return ret; | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        for (i = 0; i < rt->nb_tracked_methods; i++) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            if (rt->tracked_methods[i].id != pkt_id) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                continue; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            tracked_method = rt->tracked_methods[i].name; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            del_tracked_method(rt, i); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            break; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        } | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        if (!tracked_method) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            /* Ignore this reply when the current method is not tracked. */ | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            return 0; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        } | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        if (!memcmp(tracked_method, "connect", 7)) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            if (!rt->is_input) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                if ((ret = gen_release_stream(s, rt)) < 0) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                    goto invoke_fail; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                if ((ret = gen_fcpublish_stream(s, rt)) < 0) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                    goto invoke_fail; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            } else { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                if ((ret = gen_server_bw(s, rt)) < 0) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                    goto invoke_fail; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            } | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            if ((ret = gen_create_stream(s, rt)) < 0) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                goto invoke_fail; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            if (rt->is_input) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                /* Send the FCSubscribe command when the name of live | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                 * stream is defined by the user or if it's a live stream. */ | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                if (rt->subscribe) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                    if ((ret = gen_fcsubscribe_stream(s, rt, | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                                                      rt->subscribe)) < 0) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                        goto invoke_fail; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                } else if (rt->live == -1) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                    if ((ret = gen_fcsubscribe_stream(s, rt, | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                                                      rt->playpath)) < 0) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                        goto invoke_fail; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                } | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            } | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        } else if (!memcmp(tracked_method, "createStream", 12)) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            //extract a number from the result | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n"); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            } else { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                rt->main_channel_id = av_int2double(AV_RB64(pkt->data + 21)); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            } | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            if (!rt->is_input) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                if ((ret = gen_publish(s, rt)) < 0) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                    goto invoke_fail; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            } else { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                if ((ret = gen_play(s, rt)) < 0) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                    goto invoke_fail; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                if ((ret = gen_buffer_time(s, rt)) < 0) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                    goto invoke_fail; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            } | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        } | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) { | 
																 | 
																 | 
																    } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) { | 
															
														
														
													
														
															
																 | 
																 | 
																        const uint8_t* ptr = pkt->data + 11; | 
																 | 
																 | 
																        const uint8_t* ptr = pkt->data + 11; | 
															
														
														
													
														
															
																 | 
																 | 
																        uint8_t tmpstr[256]; | 
																 | 
																 | 
																        uint8_t tmpstr[256]; | 
															
														
														
													
												
													
														
															
																| 
																	
																		
																	
																	
																		
																	
																	
																 | 
																@@ -1134,8 +1145,6 @@ static int handle_invoke(URLContext *s, RTMPPacket *pkt) | 
															
														
														
													
														
															
																 | 
																 | 
																            return ret; | 
																 | 
																 | 
																            return ret; | 
															
														
														
													
														
															
																 | 
																 | 
																    } | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																invoke_fail: | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    av_free(tracked_method); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    return ret; | 
																 | 
																 | 
																    return ret; | 
															
														
														
													
														
															
																 | 
																 | 
																} | 
																 | 
																 | 
																} | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
												
													
														
															
																| 
																	
																		
																	
																	
																	
																 | 
																
  |