comparison mmst.c @ 6367:c58f5d360b4e libavformat

Extract fields that are to be shared between MMST/MMSH into a common struct, MMSContext. The other MMST-specific members go into MMSTContext. Patch by Zhentan Feng <spyfeng gmail com>.
author rbultje
date Wed, 11 Aug 2010 22:43:54 +0000
parents d4691e73420f
children 1423af8f47f7
comparison
equal deleted inserted replaced
6366:d4691e73420f 6367:c58f5d360b4e
86 typedef struct { 86 typedef struct {
87 int id; 87 int id;
88 }MMSStream; 88 }MMSStream;
89 89
90 typedef struct { 90 typedef struct {
91 int outgoing_packet_seq; ///< Outgoing packet sequence number.
92 char path[256]; ///< Path of the resource being asked for.
93 char host[128]; ///< Host of the resources.
94
95 URLContext *mms_hd; ///< TCP connection handle 91 URLContext *mms_hd; ///< TCP connection handle
96 MMSStream streams[MAX_STREAMS]; 92 MMSStream streams[MAX_STREAMS];
97 93
98 /** Buffer for outgoing packets. */ 94 /** Buffer for outgoing packets. */
99 /*@{*/ 95 /*@{*/
106 uint8_t in_buffer[8192]; ///< Buffer for incoming packets. 102 uint8_t in_buffer[8192]; ///< Buffer for incoming packets.
107 uint8_t *read_in_ptr; ///< Pointer for reading from incoming buffer. 103 uint8_t *read_in_ptr; ///< Pointer for reading from incoming buffer.
108 int remaining_in_len; ///< Reading length from incoming buffer. 104 int remaining_in_len; ///< Reading length from incoming buffer.
109 /*@}*/ 105 /*@}*/
110 106
111 int incoming_packet_seq; ///< Incoming packet sequence number.
112 int incoming_flags; ///< Incoming packet flags.
113
114 int packet_id; ///< Identifier for packets in the current stream.
115 unsigned int header_packet_id; ///< default is 2.
116 107
117 /** Internal handling of the ASF header */ 108 /** Internal handling of the ASF header */
118 /*@{*/ 109 /*@{*/
119 uint8_t *asf_header; ///< Stored ASF header. 110 uint8_t *asf_header; ///< Stored ASF header.
120 int asf_header_size; ///< Size of stored ASF header. 111 int asf_header_size; ///< Size of stored ASF header.
124 /*@}*/ 115 /*@}*/
125 116
126 int stream_num; ///< stream numbers. 117 int stream_num; ///< stream numbers.
127 } MMSContext; 118 } MMSContext;
128 119
120 typedef struct {
121 MMSContext mms;
122 int outgoing_packet_seq; ///< Outgoing packet sequence number.
123 char path[256]; ///< Path of the resource being asked for.
124 char host[128]; ///< Host of the resources.
125 int incoming_packet_seq; ///< Incoming packet sequence number.
126 int incoming_flags; ///< Incoming packet flags.
127 int packet_id; ///< Identifier for packets in the current stream.
128 unsigned int header_packet_id; ///< default is 2.
129 } MMSTContext;
130
129 /** Create MMST command packet header */ 131 /** Create MMST command packet header */
130 static void start_command_packet(MMSContext *mms, MMSCSPacketType packet_type) 132 static void start_command_packet(MMSTContext *mmst, MMSCSPacketType packet_type)
131 { 133 {
134 MMSContext *mms = &mmst->mms;
132 mms->write_out_ptr = mms->out_buffer; 135 mms->write_out_ptr = mms->out_buffer;
133 136
134 bytestream_put_le32(&mms->write_out_ptr, 1); // start sequence 137 bytestream_put_le32(&mms->write_out_ptr, 1); // start sequence
135 bytestream_put_le32(&mms->write_out_ptr, 0xb00bface); 138 bytestream_put_le32(&mms->write_out_ptr, 0xb00bface);
136 bytestream_put_le32(&mms->write_out_ptr, 0); // Length starts from after the protocol type bytes 139 bytestream_put_le32(&mms->write_out_ptr, 0); // Length starts from after the protocol type bytes
137 bytestream_put_le32(&mms->write_out_ptr, MKTAG('M','M','S',' ')); 140 bytestream_put_le32(&mms->write_out_ptr, MKTAG('M','M','S',' '));
138 bytestream_put_le32(&mms->write_out_ptr, 0); 141 bytestream_put_le32(&mms->write_out_ptr, 0);
139 bytestream_put_le32(&mms->write_out_ptr, mms->outgoing_packet_seq++); 142 bytestream_put_le32(&mms->write_out_ptr, mmst->outgoing_packet_seq++);
140 bytestream_put_le64(&mms->write_out_ptr, 0); // timestamp 143 bytestream_put_le64(&mms->write_out_ptr, 0); // timestamp
141 bytestream_put_le32(&mms->write_out_ptr, 0); 144 bytestream_put_le32(&mms->write_out_ptr, 0);
142 bytestream_put_le16(&mms->write_out_ptr, packet_type); 145 bytestream_put_le16(&mms->write_out_ptr, packet_type);
143 bytestream_put_le16(&mms->write_out_ptr, 3); // direction to server 146 bytestream_put_le16(&mms->write_out_ptr, 3); // direction to server
144 } 147 }
150 bytestream_put_le32(&mms->write_out_ptr, prefix1); // first prefix 153 bytestream_put_le32(&mms->write_out_ptr, prefix1); // first prefix
151 bytestream_put_le32(&mms->write_out_ptr, prefix2); // second prefix 154 bytestream_put_le32(&mms->write_out_ptr, prefix2); // second prefix
152 } 155 }
153 156
154 /** Send a prepared MMST command packet. */ 157 /** Send a prepared MMST command packet. */
155 static int send_command_packet(MMSContext *mms) 158 static int send_command_packet(MMSTContext *mmst)
156 { 159 {
160 MMSContext *mms = &mmst->mms;
157 int len= mms->write_out_ptr - mms->out_buffer; 161 int len= mms->write_out_ptr - mms->out_buffer;
158 int exact_length = FFALIGN(len, 8); 162 int exact_length = FFALIGN(len, 8);
159 int first_length= exact_length - 16; 163 int first_length= exact_length - 16;
160 int len8= first_length/8; 164 int len8= first_length/8;
161 int write_result; 165 int write_result;
190 194
191 len = ff_put_str16_nolen(&bic, src); 195 len = ff_put_str16_nolen(&bic, src);
192 mms->write_out_ptr += len; 196 mms->write_out_ptr += len;
193 } 197 }
194 198
195 static int send_time_test_data(MMSContext *mms) 199 static int send_time_test_data(MMSTContext *mmst)
196 { 200 {
197 start_command_packet(mms, CS_PKT_TIMING_DATA_REQUEST); 201 start_command_packet(mmst, CS_PKT_TIMING_DATA_REQUEST);
198 insert_command_prefixes(mms, 0xf0f0f0f1, 0x0004000b); 202 insert_command_prefixes(&mmst->mms, 0xf0f0f0f1, 0x0004000b);
199 return send_command_packet(mms); 203 return send_command_packet(mmst);
200 } 204 }
201 205
202 static int send_protocol_select(MMSContext *mms) 206 static int send_protocol_select(MMSTContext *mmst)
203 { 207 {
204 char data_string[256]; 208 char data_string[256];
205 209 MMSContext *mms = &mmst->mms;
206 start_command_packet(mms, CS_PKT_PROTOCOL_SELECT); 210
211 start_command_packet(mmst, CS_PKT_PROTOCOL_SELECT);
207 insert_command_prefixes(mms, 0, 0xffffffff); 212 insert_command_prefixes(mms, 0, 0xffffffff);
208 bytestream_put_le32(&mms->write_out_ptr, 0); // maxFunnelBytes 213 bytestream_put_le32(&mms->write_out_ptr, 0); // maxFunnelBytes
209 bytestream_put_le32(&mms->write_out_ptr, 0x00989680); // maxbitRate 214 bytestream_put_le32(&mms->write_out_ptr, 0x00989680); // maxbitRate
210 bytestream_put_le32(&mms->write_out_ptr, 2); // funnelMode 215 bytestream_put_le32(&mms->write_out_ptr, 2); // funnelMode
211 snprintf(data_string, sizeof(data_string), "\\\\%d.%d.%d.%d\\%s\\%d", 216 snprintf(data_string, sizeof(data_string), "\\\\%d.%d.%d.%d\\%s\\%d",
215 LOCAL_ADDRESS&0xff, 220 LOCAL_ADDRESS&0xff,
216 "TCP", // or UDP 221 "TCP", // or UDP
217 LOCAL_PORT); 222 LOCAL_PORT);
218 223
219 mms_put_utf16(mms, data_string); 224 mms_put_utf16(mms, data_string);
220 return send_command_packet(mms); 225 return send_command_packet(mmst);
221 } 226 }
222 227
223 static int send_media_file_request(MMSContext *mms) 228 static int send_media_file_request(MMSTContext *mmst)
224 { 229 {
225 start_command_packet(mms, CS_PKT_MEDIA_FILE_REQUEST); 230 MMSContext *mms = &mmst->mms;
231 start_command_packet(mmst, CS_PKT_MEDIA_FILE_REQUEST);
226 insert_command_prefixes(mms, 1, 0xffffffff); 232 insert_command_prefixes(mms, 1, 0xffffffff);
227 bytestream_put_le32(&mms->write_out_ptr, 0); 233 bytestream_put_le32(&mms->write_out_ptr, 0);
228 bytestream_put_le32(&mms->write_out_ptr, 0); 234 bytestream_put_le32(&mms->write_out_ptr, 0);
229 mms_put_utf16(mms, mms->path + 1); // +1 for skip "/" 235 mms_put_utf16(mms, mmst->path + 1); // +1 for skip "/"
230 236
231 return send_command_packet(mms); 237 return send_command_packet(mmst);
232 } 238 }
233 239
234 static void handle_packet_stream_changing_type(MMSContext *mms) 240 static void handle_packet_stream_changing_type(MMSTContext *mmst)
235 { 241 {
242 MMSContext *mms = &mmst->mms;
236 dprintf(NULL, "Stream changing!\n"); 243 dprintf(NULL, "Stream changing!\n");
237 244
238 // 40 is the packet header size, 7 is the prefix size. 245 // 40 is the packet header size, 7 is the prefix size.
239 mms->header_packet_id= AV_RL32(mms->in_buffer + 40 + 7); 246 mmst->header_packet_id= AV_RL32(mms->in_buffer + 40 + 7);
240 dprintf(NULL, "Changed header prefix to 0x%x", mms->header_packet_id); 247 dprintf(NULL, "Changed header prefix to 0x%x", mmst->header_packet_id);
241 } 248 }
242 249
243 static int send_keepalive_packet(MMSContext *mms) 250 static int send_keepalive_packet(MMSTContext *mmst)
244 { 251 {
245 // respond to a keepalive with a keepalive... 252 // respond to a keepalive with a keepalive...
246 start_command_packet(mms, CS_PKT_KEEPALIVE); 253 start_command_packet(mmst, CS_PKT_KEEPALIVE);
247 insert_command_prefixes(mms, 1, 0x100FFFF); 254 insert_command_prefixes(&mmst->mms, 1, 0x100FFFF);
248 return send_command_packet(mms); 255 return send_command_packet(mmst);
249 } 256 }
250 257
251 /** Pad media packets smaller than max_packet_size and/or adjust read position 258 /** Pad media packets smaller than max_packet_size and/or adjust read position
252 * after a seek. */ 259 * after a seek. */
253 static void pad_media_packet(MMSContext *mms) 260 static void pad_media_packet(MMSContext *mms)
258 mms->remaining_in_len += padding_size; 265 mms->remaining_in_len += padding_size;
259 } 266 }
260 } 267 }
261 268
262 /** Read incoming MMST media, header or command packet. */ 269 /** Read incoming MMST media, header or command packet. */
263 static MMSSCPacketType get_tcp_server_response(MMSContext *mms) 270 static MMSSCPacketType get_tcp_server_response(MMSTContext *mmst)
264 { 271 {
265 int read_result; 272 int read_result;
266 MMSSCPacketType packet_type= -1; 273 MMSSCPacketType packet_type= -1;
267 274 MMSContext *mms = &mmst->mms;
268 for(;;) { 275 for(;;) {
269 read_result = url_read_complete(mms->mms_hd, mms->in_buffer, 8); 276 read_result = url_read_complete(mms->mms_hd, mms->in_buffer, 8);
270 if (read_result != 8) { 277 if (read_result != 8) {
271 if(read_result < 0) { 278 if(read_result < 0) {
272 av_log(NULL, AV_LOG_ERROR, 279 av_log(NULL, AV_LOG_ERROR,
283 290
284 // handle command packet. 291 // handle command packet.
285 if(AV_RL32(mms->in_buffer + 4)==0xb00bface) { 292 if(AV_RL32(mms->in_buffer + 4)==0xb00bface) {
286 int length_remaining, hr; 293 int length_remaining, hr;
287 294
288 mms->incoming_flags= mms->in_buffer[3]; 295 mmst->incoming_flags= mms->in_buffer[3];
289 read_result= url_read_complete(mms->mms_hd, mms->in_buffer+8, 4); 296 read_result= url_read_complete(mms->mms_hd, mms->in_buffer+8, 4);
290 if(read_result != 4) { 297 if(read_result != 4) {
291 av_log(NULL, AV_LOG_ERROR, 298 av_log(NULL, AV_LOG_ERROR,
292 "Reading command packet length failed: %d (%s)\n", 299 "Reading command packet length failed: %d (%s)\n",
293 read_result, 300 read_result,
330 337
331 // note we cache the first 8 bytes, 338 // note we cache the first 8 bytes,
332 // then fill up the buffer with the others 339 // then fill up the buffer with the others
333 tmp = AV_RL16(mms->in_buffer + 6); 340 tmp = AV_RL16(mms->in_buffer + 6);
334 length_remaining = (tmp - 8) & 0xffff; 341 length_remaining = (tmp - 8) & 0xffff;
335 mms->incoming_packet_seq = AV_RL32(mms->in_buffer); 342 mmst->incoming_packet_seq = AV_RL32(mms->in_buffer);
336 packet_id_type = mms->in_buffer[4]; 343 packet_id_type = mms->in_buffer[4];
337 mms->incoming_flags = mms->in_buffer[5]; 344 mmst->incoming_flags = mms->in_buffer[5];
338 345
339 if (length_remaining < 0 346 if (length_remaining < 0
340 || length_remaining > sizeof(mms->in_buffer) - 8) { 347 || length_remaining > sizeof(mms->in_buffer) - 8) {
341 av_log(NULL, AV_LOG_ERROR, 348 av_log(NULL, AV_LOG_ERROR,
342 "Data length %d is invalid or too large (max=%zu)\n", 349 "Data length %d is invalid or too large (max=%zu)\n",
354 "The server closed the connection"); 361 "The server closed the connection");
355 return read_result < 0 ? read_result : AVERROR_IO; 362 return read_result < 0 ? read_result : AVERROR_IO;
356 } 363 }
357 364
358 // if we successfully read everything. 365 // if we successfully read everything.
359 if(packet_id_type == mms->header_packet_id) { 366 if(packet_id_type == mmst->header_packet_id) {
360 packet_type = SC_PKT_ASF_HEADER; 367 packet_type = SC_PKT_ASF_HEADER;
361 // Store the asf header 368 // Store the asf header
362 if(!mms->header_parsed) { 369 if(!mms->header_parsed) {
363 void *p = av_realloc(mms->asf_header, 370 void *p = av_realloc(mms->asf_header,
364 mms->asf_header_size + mms->remaining_in_len); 371 mms->asf_header_size + mms->remaining_in_len);
370 memcpy(mms->asf_header + mms->asf_header_size, 377 memcpy(mms->asf_header + mms->asf_header_size,
371 mms->read_in_ptr, mms->remaining_in_len); 378 mms->read_in_ptr, mms->remaining_in_len);
372 mms->asf_header_size += mms->remaining_in_len; 379 mms->asf_header_size += mms->remaining_in_len;
373 } 380 }
374 // 0x04 means asf header is sent in multiple packets. 381 // 0x04 means asf header is sent in multiple packets.
375 if (mms->incoming_flags == 0x04) 382 if (mmst->incoming_flags == 0x04)
376 continue; 383 continue;
377 } else if(packet_id_type == mms->packet_id) { 384 } else if(packet_id_type == mmst->packet_id) {
378 packet_type = SC_PKT_ASF_MEDIA; 385 packet_type = SC_PKT_ASF_MEDIA;
379 } else { 386 } else {
380 dprintf(NULL, "packet id type %d is old.", packet_id_type); 387 dprintf(NULL, "packet id type %d is old.", packet_id_type);
381 continue; 388 continue;
382 } 389 }
383 } 390 }
384 391
385 // preprocess some packet type 392 // preprocess some packet type
386 if(packet_type == SC_PKT_KEEPALIVE) { 393 if(packet_type == SC_PKT_KEEPALIVE) {
387 send_keepalive_packet(mms); 394 send_keepalive_packet(mmst);
388 continue; 395 continue;
389 } else if(packet_type == SC_PKT_STREAM_CHANGING) { 396 } else if(packet_type == SC_PKT_STREAM_CHANGING) {
390 handle_packet_stream_changing_type(mms); 397 handle_packet_stream_changing_type(mmst);
391 } else if(packet_type == SC_PKT_ASF_MEDIA) { 398 } else if(packet_type == SC_PKT_ASF_MEDIA) {
392 pad_media_packet(mms); 399 pad_media_packet(mms);
393 } 400 }
394 return packet_type; 401 return packet_type;
395 } 402 }
396 } 403 }
397 404
398 static int mms_safe_send_recv(MMSContext *mms, 405 static int mms_safe_send_recv(MMSTContext *mmst,
399 int (*send_fun)(MMSContext *mms), 406 int (*send_fun)(MMSTContext *mmst),
400 const MMSSCPacketType expect_type) 407 const MMSSCPacketType expect_type)
401 { 408 {
402 MMSSCPacketType type; 409 MMSSCPacketType type;
403 if(send_fun) { 410 if(send_fun) {
404 int ret = send_fun(mms); 411 int ret = send_fun(mmst);
405 if (ret < 0) { 412 if (ret < 0) {
406 dprintf(NULL, "Send Packet error before expecting recv packet %d\n", expect_type); 413 dprintf(NULL, "Send Packet error before expecting recv packet %d\n", expect_type);
407 return ret; 414 return ret;
408 } 415 }
409 } 416 }
410 417
411 if ((type = get_tcp_server_response(mms)) != expect_type) { 418 if ((type = get_tcp_server_response(mmst)) != expect_type) {
412 av_log(NULL, AV_LOG_ERROR, 419 av_log(NULL, AV_LOG_ERROR,
413 "Corrupt stream (unexpected packet type 0x%x, expected 0x%x)\n", 420 "Corrupt stream (unexpected packet type 0x%x, expected 0x%x)\n",
414 type, expect_type); 421 type, expect_type);
415 return AVERROR_INVALIDDATA; 422 return AVERROR_INVALIDDATA;
416 } else { 423 } else {
417 return 0; 424 return 0;
418 } 425 }
419 } 426 }
420 427
421 static int send_media_header_request(MMSContext *mms) 428 static int send_media_header_request(MMSTContext *mmst)
422 { 429 {
423 start_command_packet(mms, CS_PKT_MEDIA_HEADER_REQUEST); 430 MMSContext *mms = &mmst->mms;
431 start_command_packet(mmst, CS_PKT_MEDIA_HEADER_REQUEST);
424 insert_command_prefixes(mms, 1, 0); 432 insert_command_prefixes(mms, 1, 0);
425 bytestream_put_le32(&mms->write_out_ptr, 0); 433 bytestream_put_le32(&mms->write_out_ptr, 0);
426 bytestream_put_le32(&mms->write_out_ptr, 0x00800000); 434 bytestream_put_le32(&mms->write_out_ptr, 0x00800000);
427 bytestream_put_le32(&mms->write_out_ptr, 0xffffffff); 435 bytestream_put_le32(&mms->write_out_ptr, 0xffffffff);
428 bytestream_put_le32(&mms->write_out_ptr, 0); 436 bytestream_put_le32(&mms->write_out_ptr, 0);
433 bytestream_put_le32(&mms->write_out_ptr, 0); 441 bytestream_put_le32(&mms->write_out_ptr, 0);
434 bytestream_put_le32(&mms->write_out_ptr, 0x40AC2000); 442 bytestream_put_le32(&mms->write_out_ptr, 0x40AC2000);
435 bytestream_put_le32(&mms->write_out_ptr, 2); 443 bytestream_put_le32(&mms->write_out_ptr, 2);
436 bytestream_put_le32(&mms->write_out_ptr, 0); 444 bytestream_put_le32(&mms->write_out_ptr, 0);
437 445
438 return send_command_packet(mms); 446 return send_command_packet(mmst);
439 } 447 }
440 448
441 /** Send the initial handshake. */ 449 /** Send the initial handshake. */
442 static int send_startup_packet(MMSContext *mms) 450 static int send_startup_packet(MMSTContext *mmst)
443 { 451 {
444 char data_string[256]; 452 char data_string[256];
453 MMSContext *mms = &mmst->mms;
445 // SubscriberName is defined in MS specification linked below. 454 // SubscriberName is defined in MS specification linked below.
446 // The guid value can be any valid value. 455 // The guid value can be any valid value.
447 // http://download.microsoft.com/ 456 // http://download.microsoft.com/
448 // download/9/5/E/95EF66AF-9026-4BB0-A41D-A4F81802D92C/%5BMS-WMSP%5D.pdf 457 // download/9/5/E/95EF66AF-9026-4BB0-A41D-A4F81802D92C/%5BMS-WMSP%5D.pdf
449 snprintf(data_string, sizeof(data_string), 458 snprintf(data_string, sizeof(data_string),
450 "NSPlayer/7.0.0.1956; {%s}; Host: %s", 459 "NSPlayer/7.0.0.1956; {%s}; Host: %s",
451 "7E667F5D-A661-495E-A512-F55686DDA178", mms->host); 460 "7E667F5D-A661-495E-A512-F55686DDA178", mmst->host);
452 461
453 start_command_packet(mms, CS_PKT_INITIAL); 462 start_command_packet(mmst, CS_PKT_INITIAL);
454 insert_command_prefixes(mms, 0, 0x0004000b); 463 insert_command_prefixes(mms, 0, 0x0004000b);
455 bytestream_put_le32(&mms->write_out_ptr, 0x0003001c); 464 bytestream_put_le32(&mms->write_out_ptr, 0x0003001c);
456 mms_put_utf16(mms, data_string); 465 mms_put_utf16(mms, data_string);
457 return send_command_packet(mms); 466 return send_command_packet(mmst);
458 } 467 }
459 468
460 static int asf_header_parser(MMSContext *mms) 469 static int asf_header_parser(MMSContext *mms)
461 { 470 {
462 uint8_t *p = mms->asf_header; 471 uint8_t *p = mms->asf_header;
517 526
518 return 0; 527 return 0;
519 } 528 }
520 529
521 /** Send MMST stream selection command based on the AVStream->discard values. */ 530 /** Send MMST stream selection command based on the AVStream->discard values. */
522 static int send_stream_selection_request(MMSContext *mms) 531 static int send_stream_selection_request(MMSTContext *mmst)
523 { 532 {
524 int i; 533 int i;
525 534 MMSContext *mms = &mmst->mms;
526 // send the streams we want back... 535 // send the streams we want back...
527 start_command_packet(mms, CS_PKT_STREAM_ID_REQUEST); 536 start_command_packet(mmst, CS_PKT_STREAM_ID_REQUEST);
528 bytestream_put_le32(&mms->write_out_ptr, mms->stream_num); // stream nums 537 bytestream_put_le32(&mms->write_out_ptr, mms->stream_num); // stream nums
529 for(i= 0; i<mms->stream_num; i++) { 538 for(i= 0; i<mms->stream_num; i++) {
530 bytestream_put_le16(&mms->write_out_ptr, 0xffff); // flags 539 bytestream_put_le16(&mms->write_out_ptr, 0xffff); // flags
531 bytestream_put_le16(&mms->write_out_ptr, mms->streams[i].id); // stream id 540 bytestream_put_le16(&mms->write_out_ptr, mms->streams[i].id); // stream id
532 bytestream_put_le16(&mms->write_out_ptr, 0); // selection 541 bytestream_put_le16(&mms->write_out_ptr, 0); // selection
533 } 542 }
534 return send_command_packet(mms); 543 return send_command_packet(mmst);
535 } 544 }
536 545
537 static int read_data(MMSContext *mms, uint8_t *buf, const int buf_size) 546 static int read_data(MMSContext *mms, uint8_t *buf, const int buf_size)
538 { 547 {
539 int read_size; 548 int read_size;
542 mms->remaining_in_len -= read_size; 551 mms->remaining_in_len -= read_size;
543 mms->read_in_ptr += read_size; 552 mms->read_in_ptr += read_size;
544 return read_size; 553 return read_size;
545 } 554 }
546 555
547 static int send_close_packet(MMSContext *mms) 556 static int send_close_packet(MMSTContext *mmst)
548 { 557 {
549 start_command_packet(mms, CS_PKT_STREAM_CLOSE); 558 start_command_packet(mmst, CS_PKT_STREAM_CLOSE);
550 insert_command_prefixes(mms, 1, 1); 559 insert_command_prefixes(&mmst->mms, 1, 1);
551 560
552 return send_command_packet(mms); 561 return send_command_packet(mmst);
553 } 562 }
554 563
555 /** Close the MMSH/MMST connection */ 564 /** Close the MMSH/MMST connection */
556 static int mms_close(URLContext *h) 565 static int mms_close(URLContext *h)
557 { 566 {
558 MMSContext *mms = (MMSContext *)h->priv_data; 567 MMSTContext *mmst = (MMSTContext *)h->priv_data;
559 568 MMSContext *mms = &mmst->mms;
560 if(mms->mms_hd) { 569 if(mms->mms_hd) {
561 send_close_packet(mms); 570 send_close_packet(mmst);
562 url_close(mms->mms_hd); 571 url_close(mms->mms_hd);
563 } 572 }
564 573
565 /* free all separately allocated pointers in mms */ 574 /* free all separately allocated pointers in mms */
566 av_free(mms->asf_header); 575 av_free(mms->asf_header);
567 av_freep(&h->priv_data); 576 av_freep(&h->priv_data);
568 577
569 return 0; 578 return 0;
570 } 579 }
571 580
572 static int send_media_packet_request(MMSContext *mms) 581 static int send_media_packet_request(MMSTContext *mmst)
573 { 582 {
574 start_command_packet(mms, CS_PKT_START_FROM_PKT_ID); 583 MMSContext *mms = &mmst->mms;
584 start_command_packet(mmst, CS_PKT_START_FROM_PKT_ID);
575 insert_command_prefixes(mms, 1, 0x0001FFFF); 585 insert_command_prefixes(mms, 1, 0x0001FFFF);
576 bytestream_put_le64(&mms->write_out_ptr, 0); // seek timestamp 586 bytestream_put_le64(&mms->write_out_ptr, 0); // seek timestamp
577 bytestream_put_le32(&mms->write_out_ptr, 0xffffffff); // unknown 587 bytestream_put_le32(&mms->write_out_ptr, 0xffffffff); // unknown
578 bytestream_put_le32(&mms->write_out_ptr, 0xffffffff); // packet offset 588 bytestream_put_le32(&mms->write_out_ptr, 0xffffffff); // packet offset
579 bytestream_put_byte(&mms->write_out_ptr, 0xff); // max stream time limit 589 bytestream_put_byte(&mms->write_out_ptr, 0xff); // max stream time limit
580 bytestream_put_byte(&mms->write_out_ptr, 0xff); // max stream time limit 590 bytestream_put_byte(&mms->write_out_ptr, 0xff); // max stream time limit
581 bytestream_put_byte(&mms->write_out_ptr, 0xff); // max stream time limit 591 bytestream_put_byte(&mms->write_out_ptr, 0xff); // max stream time limit
582 bytestream_put_byte(&mms->write_out_ptr, 0x00); // stream time limit flag 592 bytestream_put_byte(&mms->write_out_ptr, 0x00); // stream time limit flag
583 593
584 mms->packet_id++; // new packet_id 594 mmst->packet_id++; // new packet_id
585 bytestream_put_le32(&mms->write_out_ptr, mms->packet_id); 595 bytestream_put_le32(&mms->write_out_ptr, mmst->packet_id);
586 return send_command_packet(mms); 596 return send_command_packet(mmst);
587 } 597 }
588 598
589 599
590 static void clear_stream_buffers(MMSContext *mms) 600 static void clear_stream_buffers(MMSContext *mms)
591 { 601 {
593 mms->read_in_ptr = mms->in_buffer; 603 mms->read_in_ptr = mms->in_buffer;
594 } 604 }
595 605
596 static int mms_open(URLContext *h, const char *uri, int flags) 606 static int mms_open(URLContext *h, const char *uri, int flags)
597 { 607 {
608 MMSTContext *mmst;
598 MMSContext *mms; 609 MMSContext *mms;
599 int port, err; 610 int port, err;
600 char tcpname[256]; 611 char tcpname[256];
601 612
602 h->is_streamed = 1; 613 h->is_streamed = 1;
603 mms = h->priv_data = av_mallocz(sizeof(MMSContext)); 614 mmst = h->priv_data = av_mallocz(sizeof(MMSTContext));
604 if (!h->priv_data) 615 if (!h->priv_data)
605 return AVERROR(ENOMEM); 616 return AVERROR(ENOMEM);
617 mms = &mmst->mms;
606 618
607 // only for MMS over TCP, so set proto = NULL 619 // only for MMS over TCP, so set proto = NULL
608 av_url_split(NULL, 0, NULL, 0, 620 av_url_split(NULL, 0, NULL, 0,
609 mms->host, sizeof(mms->host), &port, mms->path, 621 mmst->host, sizeof(mmst->host), &port, mmst->path,
610 sizeof(mms->path), uri); 622 sizeof(mmst->path), uri);
611 623
612 if(port<0) 624 if(port<0)
613 port = 1755; // defaut mms protocol port 625 port = 1755; // defaut mms protocol port
614 626
615 // establish tcp connection. 627 // establish tcp connection.
616 ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mms->host, port, NULL); 628 ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mmst->host, port, NULL);
617 err = url_open(&mms->mms_hd, tcpname, URL_RDWR); 629 err = url_open(&mms->mms_hd, tcpname, URL_RDWR);
618 if (err) 630 if (err)
619 goto fail; 631 goto fail;
620 632
621 mms->packet_id = 3; // default, initial value. 633 mmst->packet_id = 3; // default, initial value.
622 mms->header_packet_id = 2; // default, initial value. 634 mmst->header_packet_id = 2; // default, initial value.
623 err = mms_safe_send_recv(mms, send_startup_packet, SC_PKT_CLIENT_ACCEPTED); 635 err = mms_safe_send_recv(mmst, send_startup_packet, SC_PKT_CLIENT_ACCEPTED);
624 if (err) 636 if (err)
625 goto fail; 637 goto fail;
626 err = mms_safe_send_recv(mms, send_time_test_data, SC_PKT_TIMING_TEST_REPLY); 638 err = mms_safe_send_recv(mmst, send_time_test_data, SC_PKT_TIMING_TEST_REPLY);
627 if (err) 639 if (err)
628 goto fail; 640 goto fail;
629 err = mms_safe_send_recv(mms, send_protocol_select, SC_PKT_PROTOCOL_ACCEPTED); 641 err = mms_safe_send_recv(mmst, send_protocol_select, SC_PKT_PROTOCOL_ACCEPTED);
630 if (err) 642 if (err)
631 goto fail; 643 goto fail;
632 err = mms_safe_send_recv(mms, send_media_file_request, SC_PKT_MEDIA_FILE_DETAILS); 644 err = mms_safe_send_recv(mmst, send_media_file_request, SC_PKT_MEDIA_FILE_DETAILS);
633 if (err) 645 if (err)
634 goto fail; 646 goto fail;
635 err = mms_safe_send_recv(mms, send_media_header_request, SC_PKT_HEADER_REQUEST_ACCEPTED); 647 err = mms_safe_send_recv(mmst, send_media_header_request, SC_PKT_HEADER_REQUEST_ACCEPTED);
636 if (err) 648 if (err)
637 goto fail; 649 goto fail;
638 err = mms_safe_send_recv(mms, NULL, SC_PKT_ASF_HEADER); 650 err = mms_safe_send_recv(mmst, NULL, SC_PKT_ASF_HEADER);
639 if (err) 651 if (err)
640 goto fail; 652 goto fail;
641 if((mms->incoming_flags != 0X08) && (mms->incoming_flags != 0X0C)) 653 if((mmst->incoming_flags != 0X08) && (mmst->incoming_flags != 0X0C))
642 goto fail; 654 goto fail;
643 err = asf_header_parser(mms); 655 err = asf_header_parser(mms);
644 if (err) { 656 if (err) {
645 dprintf(NULL, "asf header parsed failed!\n"); 657 dprintf(NULL, "asf header parsed failed!\n");
646 goto fail; 658 goto fail;
649 661
650 if (!mms->asf_packet_len || !mms->stream_num) 662 if (!mms->asf_packet_len || !mms->stream_num)
651 goto fail; 663 goto fail;
652 664
653 clear_stream_buffers(mms); 665 clear_stream_buffers(mms);
654 err = mms_safe_send_recv(mms, send_stream_selection_request, SC_PKT_STREAM_ID_ACCEPTED); 666 err = mms_safe_send_recv(mmst, send_stream_selection_request, SC_PKT_STREAM_ID_ACCEPTED);
655 if (err) 667 if (err)
656 goto fail; 668 goto fail;
657 // send media packet request 669 // send media packet request
658 err = mms_safe_send_recv(mms, send_media_packet_request, SC_PKT_MEDIA_PKT_FOLLOWS); 670 err = mms_safe_send_recv(mmst, send_media_packet_request, SC_PKT_MEDIA_PKT_FOLLOWS);
659 if (err) { 671 if (err) {
660 goto fail; 672 goto fail;
661 } 673 }
662 dprintf(NULL, "Leaving open (success)\n"); 674 dprintf(NULL, "Leaving open (success)\n");
663 return 0; 675 return 0;
669 681
670 /** Read ASF data through the protocol. */ 682 /** Read ASF data through the protocol. */
671 static int mms_read(URLContext *h, uint8_t *buf, int size) 683 static int mms_read(URLContext *h, uint8_t *buf, int size)
672 { 684 {
673 /* TODO: see tcp.c:tcp_read() about a possible timeout scheme */ 685 /* TODO: see tcp.c:tcp_read() about a possible timeout scheme */
674 MMSContext *mms = h->priv_data; 686 MMSTContext *mmst = h->priv_data;
687 MMSContext *mms = &mmst->mms;
675 int result = 0; 688 int result = 0;
676 int size_to_copy; 689 int size_to_copy;
677 690
678 do { 691 do {
679 if(mms->asf_header_read_size < mms->asf_header_size) { 692 if(mms->asf_header_read_size < mms->asf_header_size) {
692 /* Read remaining packet data to buffer. 705 /* Read remaining packet data to buffer.
693 * the result can not be zero because remaining_in_len is positive.*/ 706 * the result can not be zero because remaining_in_len is positive.*/
694 result = read_data(mms, buf, size); 707 result = read_data(mms, buf, size);
695 } else { 708 } else {
696 /* Read from network */ 709 /* Read from network */
697 int err = mms_safe_send_recv(mms, NULL, SC_PKT_ASF_MEDIA); 710 int err = mms_safe_send_recv(mmst, NULL, SC_PKT_ASF_MEDIA);
698 if (err == 0) { 711 if (err == 0) {
699 if(mms->remaining_in_len>mms->asf_packet_len) { 712 if(mms->remaining_in_len>mms->asf_packet_len) {
700 av_log(NULL, AV_LOG_ERROR, 713 av_log(NULL, AV_LOG_ERROR,
701 "Incoming pktlen %d is larger than ASF pktsize %d\n", 714 "Incoming pktlen %d is larger than ASF pktsize %d\n",
702 mms->remaining_in_len, mms->asf_packet_len); 715 mms->remaining_in_len, mms->asf_packet_len);