Lines Matching refs:rt
164 static int add_tracked_method(RTMPContext *rt, const char *name, int id)
168 if (rt->nb_tracked_methods + 1 > rt->tracked_methods_size) {
169 rt->tracked_methods_size = (rt->nb_tracked_methods + 1) * 2;
170 if ((err = av_reallocp_array(&rt->tracked_methods, rt->tracked_methods_size,
171 sizeof(*rt->tracked_methods))) < 0) {
172 rt->nb_tracked_methods = 0;
173 rt->tracked_methods_size = 0;
178 rt->tracked_methods[rt->nb_tracked_methods].name = av_strdup(name);
179 if (!rt->tracked_methods[rt->nb_tracked_methods].name)
181 rt->tracked_methods[rt->nb_tracked_methods].id = id;
182 rt->nb_tracked_methods++;
187 static void del_tracked_method(RTMPContext *rt, int index)
189 memmove(&rt->tracked_methods[index], &rt->tracked_methods[index + 1],
190 sizeof(*rt->tracked_methods) * (rt->nb_tracked_methods - index - 1));
191 rt->nb_tracked_methods--;
197 RTMPContext *rt = s->priv_data;
207 for (i = 0; i < rt->nb_tracked_methods; i++) {
208 if (rt->tracked_methods[i].id != pkt_id)
211 *tracked_method = rt->tracked_methods[i].name;
212 del_tracked_method(rt, i);
219 static void free_tracked_methods(RTMPContext *rt)
223 for (i = 0; i < rt->nb_tracked_methods; i ++)
224 av_freep(&rt->tracked_methods[i].name);
225 av_freep(&rt->tracked_methods);
226 rt->tracked_methods_size = 0;
227 rt->nb_tracked_methods = 0;
230 static int rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track)
247 if ((ret = add_tracked_method(rt, name, pkt_id)) < 0)
251 ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
252 &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
321 static int gen_connect(URLContext *s, RTMPContext *rt)
334 ff_amf_write_number(&p, ++rt->nb_invokes);
337 ff_amf_write_string2(&p, rt->app, rt->auth_params);
339 if (!rt->is_input) {
344 ff_amf_write_string(&p, rt->flashver);
346 if (rt->swfurl || rt->swfverify) {
348 if (rt->swfurl)
349 ff_amf_write_string(&p, rt->swfurl);
351 ff_amf_write_string(&p, rt->swfverify);
355 ff_amf_write_string2(&p, rt->tcurl, rt->auth_params);
356 if (rt->is_input) {
372 if (rt->pageurl) {
374 ff_amf_write_string(&p, rt->pageurl);
379 if (rt->conn) {
380 char *param = rt->conn;
406 return rtmp_send_packet(rt, &pkt, 1);
412 static int read_connect(URLContext *s, RTMPContext *rt)
426 if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
427 &rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0)
483 if (!ret && strcmp(tmpstr, rt->app))
485 tmpstr, rt->app);
495 bytestream_put_be32(&p, rt->max_sent_unacked);
497 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
498 &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
509 bytestream_put_be32(&p, rt->max_sent_unacked);
512 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
513 &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
526 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
527 &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
538 bytestream_put_be32(&p, rt->out_chunk_size);
539 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
540 &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
574 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
575 &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
589 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
590 &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
600 static int gen_release_stream(URLContext *s, RTMPContext *rt)
607 0, 29 + strlen(rt->playpath))) < 0)
613 ff_amf_write_number(&p, ++rt->nb_invokes);
615 ff_amf_write_string(&p, rt->playpath);
617 return rtmp_send_packet(rt, &pkt, 1);
624 static int gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
631 0, 25 + strlen(rt->playpath))) < 0)
637 ff_amf_write_number(&p, ++rt->nb_invokes);
639 ff_amf_write_string(&p, rt->playpath);
641 return rtmp_send_packet(rt, &pkt, 1);
648 static int gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
655 0, 27 + strlen(rt->playpath))) < 0)
661 ff_amf_write_number(&p, ++rt->nb_invokes);
663 ff_amf_write_string(&p, rt->playpath);
665 return rtmp_send_packet(rt, &pkt, 0);
672 static int gen_create_stream(URLContext *s, RTMPContext *rt)
686 ff_amf_write_number(&p, ++rt->nb_invokes);
689 return rtmp_send_packet(rt, &pkt, 1);
697 static int gen_delete_stream(URLContext *s, RTMPContext *rt)
711 ff_amf_write_number(&p, ++rt->nb_invokes);
713 ff_amf_write_number(&p, rt->stream_id);
715 return rtmp_send_packet(rt, &pkt, 0);
723 static int gen_get_stream_length(URLContext *s, RTMPContext *rt)
730 0, 31 + strlen(rt->playpath))) < 0)
735 ff_amf_write_number(&p, ++rt->nb_invokes);
737 ff_amf_write_string(&p, rt->playpath);
739 return rtmp_send_packet(rt, &pkt, 1);
745 static int gen_buffer_time(URLContext *s, RTMPContext *rt)
757 bytestream_put_be32(&p, rt->stream_id);
758 bytestream_put_be32(&p, rt->client_buffer_time);
760 return rtmp_send_packet(rt, &pkt, 0);
767 static int gen_play(URLContext *s, RTMPContext *rt)
773 av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
776 0, 29 + strlen(rt->playpath))) < 0)
779 pkt.extra = rt->stream_id;
783 ff_amf_write_number(&p, ++rt->nb_invokes);
785 ff_amf_write_string(&p, rt->playpath);
786 ff_amf_write_number(&p, rt->live * 1000);
788 return rtmp_send_packet(rt, &pkt, 1);
791 static int gen_seek(URLContext *s, RTMPContext *rt, int64_t timestamp)
803 pkt.extra = rt->stream_id;
811 return rtmp_send_packet(rt, &pkt, 1);
817 static int gen_pause(URLContext *s, RTMPContext *rt, int pause, uint32_t timestamp)
829 pkt.extra = rt->stream_id;
838 return rtmp_send_packet(rt, &pkt, 1);
844 static int gen_publish(URLContext *s, RTMPContext *rt)
850 av_log(s, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath);
853 0, 30 + strlen(rt->playpath))) < 0)
856 pkt.extra = rt->stream_id;
860 ff_amf_write_number(&p, ++rt->nb_invokes);
862 ff_amf_write_string(&p, rt->playpath);
865 return rtmp_send_packet(rt, &pkt, 1);
871 static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
891 return rtmp_send_packet(rt, &pkt, 0);
897 static int gen_swf_verification(URLContext *s, RTMPContext *rt)
910 memcpy(p, rt->swfverification, 42);
912 return rtmp_send_packet(rt, &pkt, 0);
918 static int gen_window_ack_size(URLContext *s, RTMPContext *rt)
929 bytestream_put_be32(&p, rt->max_sent_unacked);
931 return rtmp_send_packet(rt, &pkt, 0);
937 static int gen_check_bw(URLContext *s, RTMPContext *rt)
949 ff_amf_write_number(&p, ++rt->nb_invokes);
952 return rtmp_send_packet(rt, &pkt, 1);
958 static int gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
969 bytestream_put_be32(&p, rt->bytes_read);
971 return rtmp_send_packet(rt, &pkt, 0);
974 static int gen_fcsubscribe_stream(URLContext *s, RTMPContext *rt,
987 ff_amf_write_number(&p, ++rt->nb_invokes);
991 return rtmp_send_packet(rt, &pkt, 1);
1045 static int rtmp_calc_swf_verification(URLContext *s, RTMPContext *rt,
1051 if (rt->swfhash_len != 32) {
1057 p = &rt->swfverification[0];
1060 bytestream_put_be32(&p, rt->swfsize);
1061 bytestream_put_be32(&p, rt->swfsize);
1063 if ((ret = ff_rtmp_calc_digest(rt->swfhash, 32, 0, buf, 32, p)) < 0)
1115 RTMPContext *rt = s->priv_data;
1124 if ((ret = ffurl_open_whitelist(&stream, rt->swfverify, AVIO_FLAG_READ,
1127 av_log(s, AV_LOG_ERROR, "Cannot open connection %s.\n", rt->swfverify);
1184 av_opt_set_bin(rt, "rtmp_swfhash", swfhash, 32, 0);
1185 rt->swfsize = swfsize;
1200 static int rtmp_handshake(URLContext *s, RTMPContext *rt)
1225 if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1237 if ((ret = ff_rtmpe_gen_pub_key(rt->stream, tosend + 1)) < 0)
1241 client_pos = rtmp_handshake_imprint_with_digest(tosend + 1, rt->encrypted);
1245 if ((ret = ffurl_write(rt->stream, tosend,
1251 if ((ret = ffurl_read_complete(rt->stream, serverdata,
1257 if ((ret = ffurl_read_complete(rt->stream, clientdata,
1267 if (rt->is_input && serverdata[5] >= 3) {
1286 if (rt->swfsize) {
1287 if ((ret = rtmp_calc_swf_verification(s, rt, serverdata + 1 +
1303 if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1306 if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1311 ff_rtmpe_encrypt_sig(rt->stream, signature, digest, serverdata[0]);
1333 if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1335 ff_rtmpe_encrypt_sig(rt->stream, tosend +
1341 if ((ret = ffurl_write(rt->stream, tosend,
1345 if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1347 if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1351 if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1354 if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1360 ff_rtmpe_encrypt_sig(rt->stream, signature, digest,
1365 if ((ret = ffurl_write(rt->stream, serverdata + 1,
1369 if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1371 if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1379 static int rtmp_receive_hs_packet(RTMPContext* rt, uint32_t *first_int,
1385 inoutsize = ffurl_read_complete(rt->stream, arraydata,
1390 av_log(rt, AV_LOG_ERROR, "Erroneous Message size %d"
1400 static int rtmp_send_hs_packet(RTMPContext* rt, uint32_t first_int,
1407 inoutsize = ffurl_write(rt->stream, arraydata,
1410 av_log(rt, AV_LOG_ERROR, "Unable to write answer\n");
1420 static int rtmp_server_handshake(URLContext *s, RTMPContext *rt)
1433 inoutsize = ffurl_read_complete(rt->stream, buffer, 1); // Receive C0
1443 if (ffurl_write(rt->stream, buffer, 1) <= 0) { // Send S0
1449 ret = rtmp_receive_hs_packet(rt, &hs_epoch, &zeroes, hs_c1,
1463 ret = rtmp_send_hs_packet(rt, hs_my_epoch, 0, hs_s1,
1470 ret = rtmp_send_hs_packet(rt, hs_epoch, 0, hs_c1,
1477 ret = rtmp_receive_hs_packet(rt, &temp, &zeroes, buffer,
1496 RTMPContext *rt = s->priv_data;
1506 if (!rt->is_input) {
1509 if ((ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
1510 &rt->prev_pkt[1], &rt->nb_prev_pkt[1])) < 0)
1512 rt->out_chunk_size = AV_RB32(pkt->data);
1515 rt->in_chunk_size = AV_RB32(pkt->data);
1516 if (rt->in_chunk_size <= 0) {
1518 rt->in_chunk_size);
1522 rt->in_chunk_size);
1529 RTMPContext *rt = s->priv_data;
1540 if ((ret = gen_pong(s, rt, pkt)) < 0)
1543 if (rt->swfsize) {
1544 if ((ret = gen_swf_verification(s, rt)) < 0)
1556 RTMPContext *rt = s->priv_data;
1569 rt->max_sent_unacked = AV_RB32(pkt->data);
1570 if (rt->max_sent_unacked <= 0) {
1572 rt->max_sent_unacked);
1576 av_log(s, AV_LOG_DEBUG, "Max sent, unacked = %d\n", rt->max_sent_unacked);
1583 RTMPContext *rt = s->priv_data;
1592 rt->receive_report_size = AV_RB32(pkt->data);
1593 if (rt->receive_report_size <= 0) {
1595 rt->receive_report_size);
1598 av_log(s, AV_LOG_DEBUG, "Window acknowledgement size = %d\n", rt->receive_report_size);
1602 rt->receive_report_size >>= 1;
1607 static int do_adobe_auth(RTMPContext *rt, const char *user, const char *salt,
1621 av_md5_update(md5, rt->password, strlen(rt->password));
1635 snprintf(rt->auth_params, sizeof(rt->auth_params),
1639 av_strlcatf(rt->auth_params, sizeof(rt->auth_params),
1646 static int do_llnw_auth(RTMPContext *rt, const char *user, const char *nonce)
1666 av_md5_update(md5, rt->password, strlen(rt->password));
1673 av_md5_update(md5, rt->app, strlen(rt->app));
1674 if (!strchr(rt->app, '/'))
1695 snprintf(rt->auth_params, sizeof(rt->auth_params),
1705 RTMPContext *rt = s->priv_data;
1722 if (!rt->username[0] || !rt->password[0]) {
1735 if (rt->auth_tried) {
1740 rt->auth_params[0] = '\0';
1743 snprintf(rt->auth_params, sizeof(rt->auth_params),
1744 "?authmod=%s&user=%s", authmod, rt->username);
1783 if ((ret = do_adobe_auth(rt, user, salt, opaque, challenge)) < 0)
1786 if ((ret = do_llnw_auth(rt, user, nonce)) < 0)
1790 rt->auth_tried = 1;
1796 RTMPContext *rt = s->priv_data;
1816 level = rt->live ? AV_LOG_DEBUG : AV_LOG_WARNING;
1821 rt->do_reconnect = 1;
1835 RTMPContext *rt = s->priv_data;
1849 bytestream2_put_be32(&pbc, rt->nb_streamid);
1851 ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1852 &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
1862 RTMPContext *rt = s->priv_data;
1894 ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1895 &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
1903 RTMPContext *rt = s->priv_data;
1953 rt->state = STATE_RECEIVING;
1979 rt->state = STATE_SENDING;
1994 rt->nb_streamid++;
1995 if (rt->nb_streamid == 0 || rt->nb_streamid == 2)
1996 rt->nb_streamid++; /* Values 0 and 2 are reserved */
1997 ff_amf_write_number(&pp, rt->nb_streamid);
2004 ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
2005 &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
2051 RTMPContext *rt = s->priv_data;
2064 if (!rt->is_input) {
2065 if ((ret = gen_release_stream(s, rt)) < 0)
2068 if ((ret = gen_fcpublish_stream(s, rt)) < 0)
2071 if ((ret = gen_window_ack_size(s, rt)) < 0)
2075 if ((ret = gen_create_stream(s, rt)) < 0)
2078 if (rt->is_input) {
2081 if (rt->subscribe) {
2082 if ((ret = gen_fcsubscribe_stream(s, rt, rt->subscribe)) < 0)
2084 } else if (rt->live == -1) {
2085 if ((ret = gen_fcsubscribe_stream(s, rt, rt->playpath)) < 0)
2094 rt->stream_id = stream_id;
2097 if (!rt->is_input) {
2098 if ((ret = gen_publish(s, rt)) < 0)
2101 if (rt->live != -1) {
2102 if ((ret = gen_get_stream_length(s, rt)) < 0)
2105 if ((ret = gen_play(s, rt)) < 0)
2107 if ((ret = gen_buffer_time(s, rt)) < 0)
2111 if (read_number_result(pkt, &rt->duration)) {
2123 RTMPContext *rt = s->priv_data;
2149 if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
2150 if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
2151 if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
2152 if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
2153 if (!t && !strcmp(tmpstr, "NetStream.Seek.Notify")) rt->state = STATE_PLAYING;
2160 RTMPContext *rt = s->priv_data;
2174 if ((ret = gen_check_bw(s, rt)) < 0)
2189 static int update_offset(RTMPContext *rt, int size)
2194 if (rt->flv_off < rt->flv_size) {
2196 old_flv_size = rt->flv_size;
2197 rt->flv_size += size;
2201 rt->flv_size = size;
2202 rt->flv_off = 0;
2208 static int append_flv_data(RTMPContext *rt, RTMPPacket *pkt, int skip)
2217 rt->has_audio = 1;
2219 rt->has_video = 1;
2222 old_flv_size = update_offset(rt, size + 15);
2224 if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) {
2225 rt->flv_size = rt->flv_off = 0;
2228 bytestream2_init_writer(&pbc, rt->flv_data, rt->flv_size);
2243 RTMPContext *rt = s->priv_data;
2259 rt->received_metadata = 1;
2275 rt->has_video = 1;
2278 rt->has_audio = 1;
2295 return append_flv_data(rt, pkt, skip);
2304 static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
2349 static int handle_metadata(RTMPContext *rt, RTMPPacket *pkt)
2357 old_flv_size = update_offset(rt, pkt->size);
2359 if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) {
2360 rt->flv_size = rt->flv_off = 0;
2365 p = rt->flv_data + old_flv_size;
2390 if (p != rt->flv_data + rt->flv_size) {
2391 av_log(rt, AV_LOG_WARNING, "Incomplete flv packets in "
2393 rt->flv_size = p - rt->flv_data;
2412 RTMPContext *rt = s->priv_data;
2415 if (rt->state == STATE_STOPPED)
2420 if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
2421 rt->in_chunk_size, &rt->prev_pkt[0],
2422 &rt->nb_prev_pkt[0])) <= 0) {
2431 rt->last_timestamp = rpkt.timestamp;
2433 rt->bytes_read += ret;
2434 if (rt->bytes_read - rt->last_bytes_read > rt->receive_report_size) {
2436 if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0) {
2440 rt->last_bytes_read = rt->bytes_read;
2443 ret = rtmp_parse_result(s, rt, &rpkt);
2448 if (rt->state == STATE_SEEKING) {
2459 if (rt->do_reconnect && for_header) {
2463 if (rt->state == STATE_STOPPED) {
2467 if (for_header && (rt->state == STATE_PLAYING ||
2468 rt->state == STATE_PUBLISHING ||
2469 rt->state == STATE_SENDING ||
2470 rt->state == STATE_RECEIVING)) {
2474 if (!rpkt.size || !rt->is_input) {
2479 ret = append_flv_data(rt, &rpkt, 0);
2487 ret = handle_metadata(rt, &rpkt);
2497 RTMPContext *rt = h->priv_data;
2500 if (!rt->is_input) {
2501 rt->flv_data = NULL;
2502 if (rt->out_pkt.size)
2503 ff_rtmp_packet_destroy(&rt->out_pkt);
2504 if (rt->state > STATE_FCPUBLISH)
2505 ret = gen_fcunpublish_stream(h, rt);
2507 if (rt->state > STATE_HANDSHAKED)
2508 ret = gen_delete_stream(h, rt);
2510 for (j = 0; j < rt->nb_prev_pkt[i]; j++)
2511 ff_rtmp_packet_destroy(&rt->prev_pkt[i][j]);
2512 av_freep(&rt->prev_pkt[i]);
2515 free_tracked_methods(rt);
2516 av_freep(&rt->flv_data);
2517 ffurl_closep(&rt->stream);
2531 static int inject_fake_duration_metadata(RTMPContext *rt)
2539 uint8_t* old_flv_data = rt->flv_data;
2541 if (!(rt->flv_data = av_malloc(rt->flv_size + 55))) {
2542 rt->flv_data = old_flv_data;
2547 memcpy(rt->flv_data, old_flv_data, 13);
2549 memcpy(rt->flv_data + 13 + 55, old_flv_data + 13, rt->flv_size - 13);
2551 rt->flv_size += 55;
2555 p = rt->flv_data + 13;
2575 bytestream_put_be64(&p, av_double2int(rt->duration));
2596 RTMPContext *rt = s->priv_data;
2603 if (rt->listen_timeout > 0)
2604 rt->listen = 1;
2606 rt->is_input = !(flags & AVIO_FLAG_WRITE);
2625 av_strlcpy(rt->username, auth, sizeof(rt->username));
2626 av_strlcpy(rt->password, ptr + 1, sizeof(rt->password));
2630 if (rt->listen && strcmp(proto, "rtmp")) {
2652 rt->encrypted = 1;
2657 if (rt->listen)
2660 rt->listen_timeout * 1000, rt->tcp_nodelay);
2662 ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, "?tcp_nodelay=%d", rt->tcp_nodelay);
2666 if ((ret = ffurl_open_whitelist(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
2673 if (rt->swfverify) {
2678 rt->state = STATE_START;
2679 if (!rt->listen && (ret = rtmp_handshake(s, rt)) < 0)
2681 if (rt->listen && (ret = rtmp_server_handshake(s, rt)) < 0)
2684 rt->out_chunk_size = 128;
2685 rt->in_chunk_size = 128; // Probably overwritten later
2686 rt->state = STATE_HANDSHAKED;
2689 old_app = rt->app;
2691 rt->app = av_malloc(APP_MAX_LENGTH);
2692 if (!rt->app) {
2702 av_strlcpy(rt->app, path + 1, APP_MAX_LENGTH);
2713 memcpy(rt->app, "ondemand", 9);
2724 av_strlcpy(rt->app, next, APP_MAX_LENGTH);
2732 av_strlcpy(rt->app, path + 1, FFMIN(p - path, APP_MAX_LENGTH));
2735 av_strlcpy(rt->app, path + 1, FFMIN(fname - path - 1, APP_MAX_LENGTH));
2746 av_free(rt->app);
2747 rt->app = old_app;
2750 if (!rt->playpath) {
2754 rt->playpath = av_malloc(max_len);
2755 if (!rt->playpath) {
2765 memcpy(rt->playpath, "mp4:", 5);
2769 rt->playpath[0] = 0;
2771 av_strlcat(rt->playpath, fname, max_len);
2773 rt->playpath[0] = '\0';
2777 if (!rt->tcurl) {
2778 rt->tcurl = av_malloc(TCURL_MAX_LENGTH);
2779 if (!rt->tcurl) {
2783 ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
2784 port, "/%s", rt->app);
2787 if (!rt->flashver) {
2788 rt->flashver = av_malloc(FLASHVER_MAX_LENGTH);
2789 if (!rt->flashver) {
2793 if (rt->is_input) {
2794 snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
2798 snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
2803 rt->receive_report_size = 1048576;
2804 rt->bytes_read = 0;
2805 rt->has_audio = 0;
2806 rt->has_video = 0;
2807 rt->received_metadata = 0;
2808 rt->last_bytes_read = 0;
2809 rt->max_sent_unacked = 2500000;
2810 rt->duration = 0;
2813 proto, path, rt->app, rt->playpath);
2814 if (!rt->listen) {
2815 if ((ret = gen_connect(s, rt)) < 0)
2828 if (rt->do_reconnect) {
2830 ffurl_closep(&rt->stream);
2831 rt->do_reconnect = 0;
2832 rt->nb_invokes = 0;
2834 memset(rt->prev_pkt[i], 0,
2835 sizeof(**rt->prev_pkt) * rt->nb_prev_pkt[i]);
2836 free_tracked_methods(rt);
2840 if (rt->is_input) {
2842 rt->flv_size = 13;
2843 if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0)
2845 rt->flv_off = 0;
2846 memcpy(rt->flv_data, "FLV\1\0\0\0\0\011\0\0\0\0", rt->flv_size);
2853 while (!rt->has_audio && !rt->has_video && !rt->received_metadata) {
2861 if (rt->has_audio) {
2862 rt->flv_data[4] |= FLV_HEADER_FLAG_HASAUDIO;
2864 if (rt->has_video) {
2865 rt->flv_data[4] |= FLV_HEADER_FLAG_HASVIDEO;
2871 if (!rt->received_metadata && rt->duration > 0) {
2872 if ((ret = inject_fake_duration_metadata(rt)) < 0)
2876 rt->flv_size = 0;
2877 rt->flv_data = NULL;
2878 rt->flv_off = 0;
2879 rt->skip_bytes = 13;
2882 s->max_packet_size = rt->stream->max_packet_size;
2887 av_freep(&rt->playpath);
2888 av_freep(&rt->tcurl);
2889 av_freep(&rt->flashver);
2897 RTMPContext *rt = s->priv_data;
2902 int data_left = rt->flv_size - rt->flv_off;
2905 memcpy(buf, rt->flv_data + rt->flv_off, size);
2906 rt->flv_off += size;
2910 memcpy(buf, rt->flv_data + rt->flv_off, data_left);
2913 rt->flv_off = rt->flv_size;
2925 RTMPContext *rt = s->priv_data;
2930 if ((ret = gen_seek(s, rt, timestamp)) < 0) {
2937 rt->flv_off = rt->flv_size;
2938 rt->state = STATE_SEEKING;
2944 RTMPContext *rt = s->priv_data;
2947 rt->last_timestamp);
2948 if ((ret = gen_pause(s, rt, pause, rt->last_timestamp)) < 0) {
2950 rt->last_timestamp);
2958 RTMPContext *rt = s->priv_data;
2967 if (rt->skip_bytes) {
2968 int skip = FFMIN(rt->skip_bytes, size_temp);
2971 rt->skip_bytes -= skip;
2975 if (rt->flv_header_bytes < RTMP_HEADER) {
2976 const uint8_t *header = rt->flv_header;
2979 copy = FFMIN(RTMP_HEADER - rt->flv_header_bytes, size_temp);
2980 bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
2981 rt->flv_header_bytes += copy;
2983 if (rt->flv_header_bytes < RTMP_HEADER)
2991 rt->flv_size = pktsize;
2998 if ((ret = ff_rtmp_check_alloc_array(&rt->prev_pkt[1],
2999 &rt->nb_prev_pkt[1],
3005 rt->prev_pkt[1][channel].channel_id = 0;
3009 if ((ret = ff_rtmp_packet_create(&rt->out_pkt, channel,
3013 rt->out_pkt.extra = rt->stream_id;
3014 rt->flv_data = rt->out_pkt.data;
3017 copy = FFMIN(rt->flv_size - rt->flv_off, size_temp);
3018 bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, copy);
3019 rt->flv_off += copy;
3022 if (rt->flv_off == rt->flv_size) {
3023 rt->skip_bytes = 4;
3025 if (rt->out_pkt.type == RTMP_PT_NOTIFY) {
3034 bytestream2_init(&gbc, rt->flv_data, rt->flv_size);
3040 if ((ret = av_reallocp(&rt->out_pkt.data, rt->out_pkt.size + 16)) < 0) {
3041 rt->flv_size = rt->flv_off = rt->flv_header_bytes = 0;
3044 memmove(rt->out_pkt.data + 16, rt->out_pkt.data, rt->out_pkt.size);
3045 rt->out_pkt.size += 16;
3046 ptr = rt->out_pkt.data;
3052 if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0)
3054 rt->flv_size = 0;
3055 rt->flv_off = 0;
3056 rt->flv_header_bytes = 0;
3057 rt->flv_nb_packets++;
3061 if (rt->flv_nb_packets < rt->flush_interval)
3063 rt->flv_nb_packets = 0;
3066 rt->stream->flags |= AVIO_FLAG_NONBLOCK;
3069 ret = ffurl_read(rt->stream, &c, 1);
3072 rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
3082 if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
3083 rt->in_chunk_size,
3084 &rt->prev_pkt[0],
3085 &rt->nb_prev_pkt[0], c)) <= 0)
3088 if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)