Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: patched-ffmpeg-mt/libavformat/rtmpproto.c

Issue 789004: ffmpeg roll of source to mar 9 version... (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/ffmpeg/
Patch Set: '' Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * RTMP network protocol 2 * RTMP network protocol
3 * Copyright (c) 2009 Kostya Shishkov 3 * Copyright (c) 2009 Kostya Shishkov
4 * 4 *
5 * This file is part of FFmpeg. 5 * This file is part of FFmpeg.
6 * 6 *
7 * FFmpeg is free software; you can redistribute it and/or 7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public 8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version. 10 * version 2.1 of the License, or (at your option) any later version.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 int chunk_size; ///< size of the chunks RTMP packe ts are divided into 65 int chunk_size; ///< size of the chunks RTMP packe ts are divided into
66 int is_input; ///< input/output flag 66 int is_input; ///< input/output flag
67 char playpath[256]; ///< path to filename to play (wit h possible "mp4:" prefix) 67 char playpath[256]; ///< path to filename to play (wit h possible "mp4:" prefix)
68 char app[128]; ///< application 68 char app[128]; ///< application
69 ClientState state; ///< current state 69 ClientState state; ///< current state
70 int main_channel_id; ///< an additional channel ID whic h is used for some invocations 70 int main_channel_id; ///< an additional channel ID whic h is used for some invocations
71 uint8_t* flv_data; ///< buffer with data for demuxer 71 uint8_t* flv_data; ///< buffer with data for demuxer
72 int flv_size; ///< current buffer size 72 int flv_size; ///< current buffer size
73 int flv_off; ///< number of bytes read from cur rent buffer 73 int flv_off; ///< number of bytes read from cur rent buffer
74 RTMPPacket out_pkt; ///< rtmp packet, created from flv a/v or metadata (for output) 74 RTMPPacket out_pkt; ///< rtmp packet, created from flv a/v or metadata (for output)
75 uint32_t client_report_size; ///< number of bytes after which c lient should report to server
76 uint32_t bytes_read; ///< number of bytes read from ser ver
77 uint32_t last_bytes_read; ///< number of bytes read last rep orted to server
75 } RTMPContext; 78 } RTMPContext;
76 79
77 #define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing 80 #define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing
78 /** Client key used for digest signing */ 81 /** Client key used for digest signing */
79 static const uint8_t rtmp_player_key[] = { 82 static const uint8_t rtmp_player_key[] = {
80 'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ', 83 'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
81 'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', '0', '0', ' 1', 84 'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', '0', '0', ' 1',
82 85
83 0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02 , 86 0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02 ,
84 0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8 , 87 0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8 ,
(...skipping 18 matching lines...) Expand all
103 static void gen_connect(URLContext *s, RTMPContext *rt, const char *proto, 106 static void gen_connect(URLContext *s, RTMPContext *rt, const char *proto,
104 const char *host, int port) 107 const char *host, int port)
105 { 108 {
106 RTMPPacket pkt; 109 RTMPPacket pkt;
107 uint8_t ver[64], *p; 110 uint8_t ver[64], *p;
108 char tcurl[512]; 111 char tcurl[512];
109 112
110 ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 4096); 113 ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 4096);
111 p = pkt.data; 114 p = pkt.data;
112 115
113 snprintf(tcurl, sizeof(tcurl), "%s://%s:%d/%s", proto, host, port, rt->app); 116 ff_url_join(tcurl, sizeof(tcurl), proto, NULL, host, port, "/%s", rt->app);
114 ff_amf_write_string(&p, "connect"); 117 ff_amf_write_string(&p, "connect");
115 ff_amf_write_number(&p, 1.0); 118 ff_amf_write_number(&p, 1.0);
116 ff_amf_write_object_start(&p); 119 ff_amf_write_object_start(&p);
117 ff_amf_write_field_name(&p, "app"); 120 ff_amf_write_field_name(&p, "app");
118 ff_amf_write_string(&p, rt->app); 121 ff_amf_write_string(&p, rt->app);
119 122
120 if (rt->is_input) { 123 if (rt->is_input) {
121 snprintf(ver, sizeof(ver), "%s %d,%d,%d,%d", RTMP_CLIENT_PLATFORM, RTMP_ CLIENT_VER1, 124 snprintf(ver, sizeof(ver), "%s %d,%d,%d,%d", RTMP_CLIENT_PLATFORM, RTMP_ CLIENT_VER1,
122 RTMP_CLIENT_VER2, RTMP_CLIENT_VER3, RTMP_CLIENT_VER4); 125 RTMP_CLIENT_VER2, RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
123 } else { 126 } else {
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 uint8_t *p; 333 uint8_t *p;
331 334
332 ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, ppkt->timest amp + 1, 6); 335 ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, ppkt->timest amp + 1, 6);
333 p = pkt.data; 336 p = pkt.data;
334 bytestream_put_be16(&p, 7); 337 bytestream_put_be16(&p, 7);
335 bytestream_put_be32(&p, AV_RB32(ppkt->data+2)); 338 bytestream_put_be32(&p, AV_RB32(ppkt->data+2));
336 ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); 339 ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
337 ff_rtmp_packet_destroy(&pkt); 340 ff_rtmp_packet_destroy(&pkt);
338 } 341 }
339 342
343 /**
344 * Generates report on bytes read so far and sends it to the server.
345 */
346 static void gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
347 {
348 RTMPPacket pkt;
349 uint8_t *p;
350
351 ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_BYTES_READ, ts, 4) ;
352 p = pkt.data;
353 bytestream_put_be32(&p, rt->bytes_read);
354 ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
355 ff_rtmp_packet_destroy(&pkt);
356 }
357
340 //TODO: Move HMAC code somewhere. Eventually. 358 //TODO: Move HMAC code somewhere. Eventually.
341 #define HMAC_IPAD_VAL 0x36 359 #define HMAC_IPAD_VAL 0x36
342 #define HMAC_OPAD_VAL 0x5C 360 #define HMAC_OPAD_VAL 0x5C
343 361
344 /** 362 /**
345 * Calculates HMAC-SHA2 digest for RTMP handshake packets. 363 * Calculates HMAC-SHA2 digest for RTMP handshake packets.
346 * 364 *
347 * @param src input buffer 365 * @param src input buffer
348 * @param len input buffer length (should be 1536) 366 * @param len input buffer length (should be 1536)
349 * @param gap offset in buffer where 32 bytes should not be taken into accoun t 367 * @param gap offset in buffer where 32 bytes should not be taken into accoun t
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 av_log(LOG_CONTEXT, AV_LOG_ERROR, "Incorrect chunk size %d\n", rt->c hunk_size); 567 av_log(LOG_CONTEXT, AV_LOG_ERROR, "Incorrect chunk size %d\n", rt->c hunk_size);
550 return -1; 568 return -1;
551 } 569 }
552 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "New chunk size = %d\n", rt->chunk_siz e); 570 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "New chunk size = %d\n", rt->chunk_siz e);
553 break; 571 break;
554 case RTMP_PT_PING: 572 case RTMP_PT_PING:
555 t = AV_RB16(pkt->data); 573 t = AV_RB16(pkt->data);
556 if (t == 6) 574 if (t == 6)
557 gen_pong(s, rt, pkt); 575 gen_pong(s, rt, pkt);
558 break; 576 break;
577 case RTMP_PT_CLIENT_BW:
578 if (pkt->data_size < 4) {
579 av_log(LOG_CONTEXT, AV_LOG_ERROR,
580 "Client bandwidth report packet is less than 4 bytes long (%d )\n",
581 pkt->data_size);
582 return -1;
583 }
584 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Client bandwidth = %d\n", AV_RB32(pkt ->data));
585 rt->client_report_size = AV_RB32(pkt->data) >> 1;
586 break;
559 case RTMP_PT_INVOKE: 587 case RTMP_PT_INVOKE:
560 //TODO: check for the messages sent for wrong state? 588 //TODO: check for the messages sent for wrong state?
561 if (!memcmp(pkt->data, "\002\000\006_error", 9)) { 589 if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
562 uint8_t tmpstr[256]; 590 uint8_t tmpstr[256];
563 591
564 if (!ff_amf_get_field_value(pkt->data + 9, data_end, 592 if (!ff_amf_get_field_value(pkt->data + 9, data_end,
565 "description", tmpstr, sizeof(tmpstr))) 593 "description", tmpstr, sizeof(tmpstr)))
566 av_log(LOG_CONTEXT, AV_LOG_ERROR, "Server error: %s\n",tmpstr); 594 av_log(LOG_CONTEXT, AV_LOG_ERROR, "Server error: %s\n",tmpstr);
567 return -1; 595 return -1;
568 } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) { 596 } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 for (;;) { 690 for (;;) {
663 RTMPPacket rpkt; 691 RTMPPacket rpkt;
664 if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt, 692 if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
665 rt->chunk_size, rt->prev_pkt[0])) <= 0) { 693 rt->chunk_size, rt->prev_pkt[0])) <= 0) {
666 if (ret == 0) { 694 if (ret == 0) {
667 return AVERROR(EAGAIN); 695 return AVERROR(EAGAIN);
668 } else { 696 } else {
669 return AVERROR(EIO); 697 return AVERROR(EIO);
670 } 698 }
671 } 699 }
700 rt->bytes_read += ret;
701 if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) {
702 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Sending bytes read report\n");
703 gen_bytes_read(s, rt, rpkt.timestamp + 1);
704 rt->last_bytes_read = rt->bytes_read;
705 }
672 706
673 ret = rtmp_parse_result(s, rt, &rpkt); 707 ret = rtmp_parse_result(s, rt, &rpkt);
674 if (ret < 0) {//serious error in current packet 708 if (ret < 0) {//serious error in current packet
675 ff_rtmp_packet_destroy(&rpkt); 709 ff_rtmp_packet_destroy(&rpkt);
676 return -1; 710 return -1;
677 } 711 }
678 if (rt->state == STATE_STOPPED) { 712 if (rt->state == STATE_STOPPED) {
679 ff_rtmp_packet_destroy(&rpkt); 713 ff_rtmp_packet_destroy(&rpkt);
680 return AVERROR_EOF; 714 return AVERROR_EOF;
681 } 715 }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 uint8_t buf[2048]; 805 uint8_t buf[2048];
772 int port; 806 int port;
773 int ret; 807 int ret;
774 808
775 rt = av_mallocz(sizeof(RTMPContext)); 809 rt = av_mallocz(sizeof(RTMPContext));
776 if (!rt) 810 if (!rt)
777 return AVERROR(ENOMEM); 811 return AVERROR(ENOMEM);
778 s->priv_data = rt; 812 s->priv_data = rt;
779 rt->is_input = !(flags & URL_WRONLY); 813 rt->is_input = !(flags & URL_WRONLY);
780 814
781 url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port, 815 ff_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &por t,
782 path, sizeof(path), s->filename); 816 path, sizeof(path), s->filename);
783 817
784 if (port < 0) 818 if (port < 0)
785 port = RTMP_DEFAULT_PORT; 819 port = RTMP_DEFAULT_PORT;
786 snprintf(buf, sizeof(buf), "tcp://%s:%d", hostname, port); 820 ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
787 821
788 if (url_open(&rt->stream, buf, URL_RDWR) < 0) { 822 if (url_open(&rt->stream, buf, URL_RDWR) < 0) {
789 av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot open connection %s\n", buf); 823 av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot open connection %s\n", buf);
790 goto fail; 824 goto fail;
791 } 825 }
792 826
793 rt->state = STATE_START; 827 rt->state = STATE_START;
794 if (rtmp_handshake(s, rt)) 828 if (rtmp_handshake(s, rt))
795 return -1; 829 return -1;
796 830
(...skipping 22 matching lines...) Expand all
819 } 853 }
820 if (!strchr(fname, ':') && 854 if (!strchr(fname, ':') &&
821 (!strcmp(fname + strlen(fname) - 4, ".f4v") || 855 (!strcmp(fname + strlen(fname) - 4, ".f4v") ||
822 !strcmp(fname + strlen(fname) - 4, ".mp4"))) { 856 !strcmp(fname + strlen(fname) - 4, ".mp4"))) {
823 memcpy(rt->playpath, "mp4:", 5); 857 memcpy(rt->playpath, "mp4:", 5);
824 } else { 858 } else {
825 rt->playpath[0] = 0; 859 rt->playpath[0] = 0;
826 } 860 }
827 strncat(rt->playpath, fname, sizeof(rt->playpath) - 5); 861 strncat(rt->playpath, fname, sizeof(rt->playpath) - 5);
828 862
863 rt->client_report_size = 1048576;
864 rt->bytes_read = 0;
865 rt->last_bytes_read = 0;
866
829 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n", 867 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
830 proto, path, rt->app, rt->playpath); 868 proto, path, rt->app, rt->playpath);
831 gen_connect(s, rt, proto, hostname, port); 869 gen_connect(s, rt, proto, hostname, port);
832 870
833 do { 871 do {
834 ret = get_packet(s, 1); 872 ret = get_packet(s, 1);
835 } while (ret == EAGAIN); 873 } while (ret == EAGAIN);
836 if (ret < 0) 874 if (ret < 0)
837 goto fail; 875 goto fail;
838 876
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 } 988 }
951 989
952 URLProtocol rtmp_protocol = { 990 URLProtocol rtmp_protocol = {
953 "rtmp", 991 "rtmp",
954 rtmp_open, 992 rtmp_open,
955 rtmp_read, 993 rtmp_read,
956 rtmp_write, 994 rtmp_write,
957 NULL, /* seek */ 995 NULL, /* seek */
958 rtmp_close, 996 rtmp_close,
959 }; 997 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698