comparison rtmppkt.c @ 5604:81b2509db2ad libavformat

Make RTMP send/receive packet functions report number of bytes read or sent.
author kostya
date Sat, 30 Jan 2010 09:24:52 +0000
parents 8efa6bc0752e
children 6d4ba584fcf2
comparison
equal deleted inserted replaced
5603:8efa6bc0752e 5604:81b2509db2ad
74 { 74 {
75 uint8_t hdr, t, buf[16]; 75 uint8_t hdr, t, buf[16];
76 int channel_id, timestamp, data_size, offset = 0; 76 int channel_id, timestamp, data_size, offset = 0;
77 uint32_t extra = 0; 77 uint32_t extra = 0;
78 enum RTMPPacketType type; 78 enum RTMPPacketType type;
79 int size = 0;
79 80
80 if (url_read(h, &hdr, 1) != 1) 81 if (url_read(h, &hdr, 1) != 1)
81 return AVERROR(EIO); 82 return AVERROR(EIO);
83 size++;
82 channel_id = hdr & 0x3F; 84 channel_id = hdr & 0x3F;
83 85
84 if (channel_id < 2) { //special case for channel number >= 64 86 if (channel_id < 2) { //special case for channel number >= 64
85 buf[1] = 0; 87 buf[1] = 0;
86 if (url_read_complete(h, buf, channel_id + 1) != channel_id + 1) 88 if (url_read_complete(h, buf, channel_id + 1) != channel_id + 1)
87 return AVERROR(EIO); 89 return AVERROR(EIO);
90 size += channel_id + 1;
88 channel_id = AV_RL16(buf) + 64; 91 channel_id = AV_RL16(buf) + 64;
89 } 92 }
90 data_size = prev_pkt[channel_id].data_size; 93 data_size = prev_pkt[channel_id].data_size;
91 type = prev_pkt[channel_id].type; 94 type = prev_pkt[channel_id].type;
92 extra = prev_pkt[channel_id].extra; 95 extra = prev_pkt[channel_id].extra;
95 if (hdr == RTMP_PS_ONEBYTE) { 98 if (hdr == RTMP_PS_ONEBYTE) {
96 timestamp = prev_pkt[channel_id].ts_delta; 99 timestamp = prev_pkt[channel_id].ts_delta;
97 } else { 100 } else {
98 if (url_read_complete(h, buf, 3) != 3) 101 if (url_read_complete(h, buf, 3) != 3)
99 return AVERROR(EIO); 102 return AVERROR(EIO);
103 size += 3;
100 timestamp = AV_RB24(buf); 104 timestamp = AV_RB24(buf);
101 if (hdr != RTMP_PS_FOURBYTES) { 105 if (hdr != RTMP_PS_FOURBYTES) {
102 if (url_read_complete(h, buf, 3) != 3) 106 if (url_read_complete(h, buf, 3) != 3)
103 return AVERROR(EIO); 107 return AVERROR(EIO);
108 size += 3;
104 data_size = AV_RB24(buf); 109 data_size = AV_RB24(buf);
105 if (url_read_complete(h, buf, 1) != 1) 110 if (url_read_complete(h, buf, 1) != 1)
106 return AVERROR(EIO); 111 return AVERROR(EIO);
112 size++;
107 type = buf[0]; 113 type = buf[0];
108 if (hdr == RTMP_PS_TWELVEBYTES) { 114 if (hdr == RTMP_PS_TWELVEBYTES) {
109 if (url_read_complete(h, buf, 4) != 4) 115 if (url_read_complete(h, buf, 4) != 4)
110 return AVERROR(EIO); 116 return AVERROR(EIO);
117 size += 4;
111 extra = AV_RL32(buf); 118 extra = AV_RL32(buf);
112 } 119 }
113 } 120 }
114 if (timestamp == 0xFFFFFF) { 121 if (timestamp == 0xFFFFFF) {
115 if (url_read_complete(h, buf, 4) != 4) 122 if (url_read_complete(h, buf, 4) != 4)
136 ff_rtmp_packet_destroy(p); 143 ff_rtmp_packet_destroy(p);
137 return AVERROR(EIO); 144 return AVERROR(EIO);
138 } 145 }
139 data_size -= chunk_size; 146 data_size -= chunk_size;
140 offset += chunk_size; 147 offset += chunk_size;
148 size += chunk_size;
141 if (data_size > 0) { 149 if (data_size > 0) {
142 url_read_complete(h, &t, 1); //marker 150 url_read_complete(h, &t, 1); //marker
151 size++;
143 if (t != (0xC0 + channel_id)) 152 if (t != (0xC0 + channel_id))
144 return -1; 153 return -1;
145 } 154 }
146 } 155 }
147 return 0; 156 return size;
148 } 157 }
149 158
150 int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt, 159 int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
151 int chunk_size, RTMPPacket *prev_pkt) 160 int chunk_size, RTMPPacket *prev_pkt)
152 { 161 {
153 uint8_t pkt_hdr[16], *p = pkt_hdr; 162 uint8_t pkt_hdr[16], *p = pkt_hdr;
154 int mode = RTMP_PS_TWELVEBYTES; 163 int mode = RTMP_PS_TWELVEBYTES;
155 int off = 0; 164 int off = 0;
165 int size = 0;
156 166
157 pkt->ts_delta = pkt->timestamp - prev_pkt[pkt->channel_id].timestamp; 167 pkt->ts_delta = pkt->timestamp - prev_pkt[pkt->channel_id].timestamp;
158 168
159 //if channel_id = 0, this is first presentation of prev_pkt, send full hdr. 169 //if channel_id = 0, this is first presentation of prev_pkt, send full hdr.
160 if (prev_pkt[pkt->channel_id].channel_id && 170 if (prev_pkt[pkt->channel_id].channel_id &&
203 prev_pkt[pkt->channel_id].ts_delta = pkt->timestamp; 213 prev_pkt[pkt->channel_id].ts_delta = pkt->timestamp;
204 } 214 }
205 prev_pkt[pkt->channel_id].extra = pkt->extra; 215 prev_pkt[pkt->channel_id].extra = pkt->extra;
206 216
207 url_write(h, pkt_hdr, p-pkt_hdr); 217 url_write(h, pkt_hdr, p-pkt_hdr);
218 size = p - pkt_hdr + pkt->data_size;
208 while (off < pkt->data_size) { 219 while (off < pkt->data_size) {
209 int towrite = FFMIN(chunk_size, pkt->data_size - off); 220 int towrite = FFMIN(chunk_size, pkt->data_size - off);
210 url_write(h, pkt->data + off, towrite); 221 url_write(h, pkt->data + off, towrite);
211 off += towrite; 222 off += towrite;
212 if (off < pkt->data_size) { 223 if (off < pkt->data_size) {
213 uint8_t marker = 0xC0 | pkt->channel_id; 224 uint8_t marker = 0xC0 | pkt->channel_id;
214 url_write(h, &marker, 1); 225 url_write(h, &marker, 1);
215 } 226 size++;
216 } 227 }
217 return 0; 228 }
229 return size;
218 } 230 }
219 231
220 int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type, 232 int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type,
221 int timestamp, int size) 233 int timestamp, int size)
222 { 234 {