FFmpeg
mmst.c
Go to the documentation of this file.
1 /*
2  * MMS protocol over TCP
3  * Copyright (c) 2006,2007 Ryan Martell
4  * Copyright (c) 2007 Björn Axelsson
5  * Copyright (c) 2010 Zhentan Feng <spyfeng at gmail dot com>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 /* References
25  * MMS protocol specification:
26  * [1]http://msdn.microsoft.com/en-us/library/cc234711(PROT.10).aspx
27  * ASF specification. Revision 01.20.03.
28  * [2]http://web.archive.org/web/20131203084402/http://msdn.microsoft.com/en-us/library/bb643323.aspx
29  */
30 
31 #include "avformat.h"
32 #include "mms.h"
33 #include "avio_internal.h"
34 #include "libavutil/intreadwrite.h"
35 #include "libavutil/mem.h"
36 #include "libavcodec/bytestream.h"
37 #include "network.h"
38 #include "url.h"
39 
40 #define LOCAL_ADDRESS 0xc0a80081 // FIXME get and use correct local ip address.
41 #define LOCAL_PORT 1037 // as above.
42 /** Client to server packet types. */
43 typedef enum {
56 
57 /** Server to client packet types. */
58 typedef enum {
59  /** Control packets. */
60  /*@{*/
73  /*@}*/
74 
75  /** Pseudo packets. */
76  /*@{*/
79  /*@}*/
80 
81  /** Data packets. */
82  /*@{*/
83  SC_PKT_ASF_HEADER = 0x010000,// make it bigger than 0xFF in case of
84  SC_PKT_ASF_MEDIA = 0x010001,// receiving false data packets.
85  /*@}*/
87 
88 typedef struct MMSTContext {
90  int outgoing_packet_seq; ///< Outgoing packet sequence number.
91  char path[256]; ///< Path of the resource being asked for.
92  char host[128]; ///< Host of the resources.
93  int incoming_packet_seq; ///< Incoming packet sequence number.
94  int incoming_flags; ///< Incoming packet flags.
95  int packet_id; ///< Identifier for packets in the current stream.
96  unsigned int header_packet_id; ///< default is 2.
97 } MMSTContext;
98 
99 /** Create MMST command packet header */
100 static void start_command_packet(MMSTContext *mmst, MMSCSPacketType packet_type)
101 {
102  MMSContext *mms = &mmst->mms;
103  mms->write_out_ptr = mms->out_buffer;
104 
105  bytestream_put_le32(&mms->write_out_ptr, 1); // start sequence
106  bytestream_put_le32(&mms->write_out_ptr, 0xb00bface);
107  bytestream_put_le32(&mms->write_out_ptr, 0); // Length starts from after the protocol type bytes
108  bytestream_put_le32(&mms->write_out_ptr, MKTAG('M','M','S',' '));
109  bytestream_put_le32(&mms->write_out_ptr, 0);
110  bytestream_put_le32(&mms->write_out_ptr, mmst->outgoing_packet_seq++);
111  bytestream_put_le64(&mms->write_out_ptr, 0); // timestamp
112  bytestream_put_le32(&mms->write_out_ptr, 0);
113  bytestream_put_le16(&mms->write_out_ptr, packet_type);
114  bytestream_put_le16(&mms->write_out_ptr, 3); // direction to server
115 }
116 
117 /** Add prefixes to MMST command packet. */
119  uint32_t prefix1, uint32_t prefix2)
120 {
121  bytestream_put_le32(&mms->write_out_ptr, prefix1); // first prefix
122  bytestream_put_le32(&mms->write_out_ptr, prefix2); // second prefix
123 }
124 
125 /** Send a prepared MMST command packet. */
127 {
128  MMSContext *mms = &mmst->mms;
129  int len= mms->write_out_ptr - mms->out_buffer;
130  int exact_length = FFALIGN(len, 8);
131  int first_length= exact_length - 16;
132  int len8= first_length/8;
133  int write_result;
134 
135  // update packet length fields.
136  AV_WL32(mms->out_buffer + 8, first_length);
137  AV_WL32(mms->out_buffer + 16, len8);
138  AV_WL32(mms->out_buffer + 32, len8-2);
139  memset(mms->write_out_ptr, 0, exact_length - len);
140 
141  // write it out.
142  write_result= ffurl_write(mms->mms_hd, mms->out_buffer, exact_length);
143  if(write_result != exact_length) {
144  av_log(mms->mms_hd, AV_LOG_ERROR,
145  "Failed to write data of length %d: %d (%s)\n",
146  exact_length, write_result,
147  write_result < 0 ? strerror(AVUNERROR(write_result)) :
148  "The server closed the connection");
149  return AVERROR(EIO);
150  }
151 
152  return 0;
153 }
154 
155 static int mms_put_utf16(MMSContext *mms, const uint8_t *src)
156 {
157  FFIOContext bic;
158  int size = mms->write_out_ptr - mms->out_buffer;
159  int len;
161  sizeof(mms->out_buffer) - size);
162 
163  len = avio_put_str16le(&bic.pub, src);
164  if (len < 0)
165  return len;
166  mms->write_out_ptr += len;
167  return 0;
168 }
169 
171 {
173  insert_command_prefixes(&mmst->mms, 0x00f0f0f0, 0x0004000b);
174  return send_command_packet(mmst);
175 }
176 
178 {
179  int ret;
180  char data_string[256];
181  MMSContext *mms = &mmst->mms;
182 
184  insert_command_prefixes(mms, 0, 0xffffffff);
185  bytestream_put_le32(&mms->write_out_ptr, 0); // maxFunnelBytes
186  bytestream_put_le32(&mms->write_out_ptr, 0x00989680); // maxbitRate
187  bytestream_put_le32(&mms->write_out_ptr, 2); // funnelMode
188  snprintf(data_string, sizeof(data_string), "\\\\%d.%d.%d.%d\\%s\\%d",
189  (LOCAL_ADDRESS>>24)&0xff,
190  (LOCAL_ADDRESS>>16)&0xff,
191  (LOCAL_ADDRESS>>8)&0xff,
192  LOCAL_ADDRESS&0xff,
193  "TCP", // or UDP
194  LOCAL_PORT);
195 
196  if ((ret = mms_put_utf16(mms, data_string)) < 0)
197  return ret;
198  return send_command_packet(mmst);
199 }
200 
202 {
203  int ret;
204  MMSContext *mms = &mmst->mms;
206  insert_command_prefixes(mms, 1, 0xffffffff);
207  bytestream_put_le32(&mms->write_out_ptr, 0);
208  bytestream_put_le32(&mms->write_out_ptr, 0);
209  if ((ret = mms_put_utf16(mms, mmst->path + 1)) < 0) // +1 for skip "/"
210  return ret;
211 
212  return send_command_packet(mmst);
213 }
214 
216 {
217  MMSContext *mms = &mmst->mms;
218  av_log(mms->mms_hd, AV_LOG_TRACE, "Stream changing!\n");
219 
220  // 40 is the packet header size, 7 is the prefix size.
221  mmst->header_packet_id= AV_RL32(mms->in_buffer + 40 + 7);
222  av_log(mms->mms_hd, AV_LOG_TRACE, "Changed header prefix to 0x%x", mmst->header_packet_id);
223 }
224 
226 {
227  // respond to a keepalive with a keepalive...
229  insert_command_prefixes(&mmst->mms, 1, 0x100FFFF);
230  return send_command_packet(mmst);
231 }
232 
233 /** Pad media packets smaller than max_packet_size and/or adjust read position
234  * after a seek. */
235 static void pad_media_packet(MMSContext *mms)
236 {
237  if(mms->remaining_in_len<mms->asf_packet_len) {
238  int padding_size = mms->asf_packet_len - mms->remaining_in_len;
239  memset(mms->in_buffer + mms->remaining_in_len, 0, padding_size);
240  mms->remaining_in_len += padding_size;
241  }
242 }
243 
244 /** Read incoming MMST media, header or command packet. */
246 {
247  int read_result;
248  MMSSCPacketType packet_type= -1;
249  MMSContext *mms = &mmst->mms;
250  for(;;) {
251  read_result = ffurl_read_complete(mms->mms_hd, mms->in_buffer, 8);
252  if (read_result != 8) {
253  if(read_result < 0) {
254  av_log(mms->mms_hd, AV_LOG_ERROR,
255  "Error reading packet header: %d (%s)\n",
256  read_result, strerror(AVUNERROR(read_result)));
257  packet_type = SC_PKT_CANCEL;
258  } else {
259  av_log(mms->mms_hd, AV_LOG_ERROR,
260  "The server closed the connection\n");
261  packet_type = SC_PKT_NO_DATA;
262  }
263  return packet_type;
264  }
265 
266  // handle command packet.
267  if(AV_RL32(mms->in_buffer + 4)==0xb00bface) {
268  int length_remaining, hr;
269 
270  mmst->incoming_flags= mms->in_buffer[3];
271  read_result= ffurl_read_complete(mms->mms_hd, mms->in_buffer+8, 4);
272  if(read_result != 4) {
273  av_log(mms->mms_hd, AV_LOG_ERROR,
274  "Reading command packet length failed: %d (%s)\n",
275  read_result,
276  read_result < 0 ? strerror(AVUNERROR(read_result)) :
277  "The server closed the connection");
278  return read_result < 0 ? read_result : AVERROR(EIO);
279  }
280 
281  length_remaining= AV_RL32(mms->in_buffer+8) + 4;
282  av_log(mms->mms_hd, AV_LOG_TRACE, "Length remaining is %d\n", length_remaining);
283  // read the rest of the packet.
284  if (length_remaining < 0
285  || length_remaining > sizeof(mms->in_buffer) - 12) {
286  av_log(mms->mms_hd, AV_LOG_ERROR,
287  "Incoming packet length %d exceeds bufsize %"SIZE_SPECIFIER"\n",
288  length_remaining, sizeof(mms->in_buffer) - 12);
289  return AVERROR_INVALIDDATA;
290  }
291  read_result = ffurl_read_complete(mms->mms_hd, mms->in_buffer + 12,
292  length_remaining) ;
293  if (read_result != length_remaining) {
294  av_log(mms->mms_hd, AV_LOG_ERROR,
295  "Reading pkt data (length=%d) failed: %d (%s)\n",
296  length_remaining, read_result,
297  read_result < 0 ? strerror(AVUNERROR(read_result)) :
298  "The server closed the connection");
299  return read_result < 0 ? read_result : AVERROR(EIO);
300  }
301  packet_type= AV_RL16(mms->in_buffer+36);
302  if (read_result >= 44 && (hr = AV_RL32(mms->in_buffer + 40))) {
303  av_log(mms->mms_hd, AV_LOG_ERROR,
304  "Server sent a message with packet type 0x%x and error status code 0x%08x\n", packet_type, hr);
305  return AVERROR(EINVAL);
306  }
307  } else {
308  int length_remaining;
309  int packet_id_type;
310  int tmp;
311 
312  // note we cache the first 8 bytes,
313  // then fill up the buffer with the others
314  tmp = AV_RL16(mms->in_buffer + 6);
315  length_remaining = (tmp - 8) & 0xffff;
316  mmst->incoming_packet_seq = AV_RL32(mms->in_buffer);
317  packet_id_type = mms->in_buffer[4];
318  mmst->incoming_flags = mms->in_buffer[5];
319 
320  if (length_remaining < 0
321  || length_remaining > sizeof(mms->in_buffer) - 8) {
322  av_log(mms->mms_hd, AV_LOG_ERROR,
323  "Data length %d is invalid or too large (max=%"SIZE_SPECIFIER")\n",
324  length_remaining, sizeof(mms->in_buffer));
325  return AVERROR_INVALIDDATA;
326  }
327  mms->remaining_in_len = length_remaining;
328  mms->read_in_ptr = mms->in_buffer;
329  read_result= ffurl_read_complete(mms->mms_hd, mms->in_buffer, length_remaining);
330  if(read_result != length_remaining) {
331  av_log(mms->mms_hd, AV_LOG_ERROR,
332  "Failed to read packet data of size %d: %d (%s)\n",
333  length_remaining, read_result,
334  read_result < 0 ? strerror(AVUNERROR(read_result)) :
335  "The server closed the connection");
336  return read_result < 0 ? read_result : AVERROR(EIO);
337  }
338 
339  // if we successfully read everything.
340  if(packet_id_type == mmst->header_packet_id) {
341  int err;
342  packet_type = SC_PKT_ASF_HEADER;
343  // Store the asf header
344  if(!mms->header_parsed) {
345  if ((err = av_reallocp(&mms->asf_header,
346  mms->asf_header_size +
347  mms->remaining_in_len)) < 0) {
348  mms->asf_header_size = 0;
349  return err;
350  }
351  memcpy(mms->asf_header + mms->asf_header_size,
352  mms->read_in_ptr, mms->remaining_in_len);
353  mms->asf_header_size += mms->remaining_in_len;
354  }
355  // 0x04 means asf header is sent in multiple packets.
356  if (mmst->incoming_flags == 0x04)
357  continue;
358  } else if(packet_id_type == mmst->packet_id) {
359  packet_type = SC_PKT_ASF_MEDIA;
360  } else {
361  av_log(mms->mms_hd, AV_LOG_TRACE, "packet id type %d is old.", packet_id_type);
362  continue;
363  }
364  }
365 
366  // preprocess some packet type
367  if(packet_type == SC_PKT_KEEPALIVE) {
368  send_keepalive_packet(mmst);
369  continue;
370  } else if(packet_type == SC_PKT_STREAM_CHANGING) {
372  } else if(packet_type == SC_PKT_ASF_MEDIA) {
373  pad_media_packet(mms);
374  }
375  return packet_type;
376  }
377 }
378 
380  int (*send_fun)(MMSTContext *mmst),
381  const MMSSCPacketType expect_type)
382 {
384  if(send_fun) {
385  int ret = send_fun(mmst);
386  if (ret < 0) {
387  av_log(NULL, AV_LOG_TRACE, "Send Packet error before expecting recv packet %d\n", expect_type);
388  return ret;
389  }
390  }
391 
392  if ((type = get_tcp_server_response(mmst)) != expect_type) {
394  "Corrupt stream (unexpected packet type 0x%x, expected 0x%x)\n",
395  type, expect_type);
396  return AVERROR_INVALIDDATA;
397  } else {
398  return 0;
399  }
400 }
401 
403 {
404  MMSContext *mms = &mmst->mms;
406  insert_command_prefixes(mms, 1, 0);
407  bytestream_put_le32(&mms->write_out_ptr, 0);
408  bytestream_put_le32(&mms->write_out_ptr, 0x00800000);
409  bytestream_put_le32(&mms->write_out_ptr, 0xffffffff);
410  bytestream_put_le32(&mms->write_out_ptr, 0);
411  bytestream_put_le32(&mms->write_out_ptr, 0);
412  bytestream_put_le32(&mms->write_out_ptr, 0);
413 
414  // the media preroll value in milliseconds?
415  bytestream_put_le32(&mms->write_out_ptr, 0);
416  bytestream_put_le32(&mms->write_out_ptr, 0x40AC2000);
417  bytestream_put_le32(&mms->write_out_ptr, 2);
418  bytestream_put_le32(&mms->write_out_ptr, 0);
419 
420  return send_command_packet(mmst);
421 }
422 
423 /** Send the initial handshake. */
425 {
426  char data_string[256];
427  int ret;
428  MMSContext *mms = &mmst->mms;
429  // SubscriberName is defined in MS specification linked below.
430  // The GUID value can be any valid value.
431  // http://download.microsoft.com/
432  // download/9/5/E/95EF66AF-9026-4BB0-A41D-A4F81802D92C/%5BMS-WMSP%5D.pdf
433  snprintf(data_string, sizeof(data_string),
434  "NSPlayer/7.0.0.1956; {%s}; Host: %s",
435  "7E667F5D-A661-495E-A512-F55686DDA178", mmst->host);
436 
438  insert_command_prefixes(mms, 0, 0x0004000b);
439  bytestream_put_le32(&mms->write_out_ptr, 0x0003001c);
440  if ((ret = mms_put_utf16(mms, data_string)) < 0)
441  return ret;
442  return send_command_packet(mmst);
443 }
444 
445 /** Send MMST stream selection command based on the AVStream->discard values. */
447 {
448  int i;
449  MMSContext *mms = &mmst->mms;
450  // send the streams we want back...
452  bytestream_put_le32(&mms->write_out_ptr, mms->stream_num); // stream nums
453  for(i= 0; i<mms->stream_num; i++) {
454  bytestream_put_le16(&mms->write_out_ptr, 0xffff); // flags
455  bytestream_put_le16(&mms->write_out_ptr, mms->streams[i].id); // stream id
456  bytestream_put_le16(&mms->write_out_ptr, 0); // selection
457  }
458  return send_command_packet(mmst);
459 }
460 
462 {
464  insert_command_prefixes(&mmst->mms, 1, 1);
465 
466  return send_command_packet(mmst);
467 }
468 
469 /** Close the MMSH/MMST connection */
470 static int mms_close(URLContext *h)
471 {
472  MMSTContext *mmst = (MMSTContext *)h->priv_data;
473  MMSContext *mms = &mmst->mms;
474  if(mms->mms_hd) {
475  send_close_packet(mmst);
476  ffurl_closep(&mms->mms_hd);
477  }
478 
479  /* free all separately allocated pointers in mms */
480  av_freep(&mms->streams);
481  av_freep(&mms->asf_header);
482 
483  return 0;
484 }
485 
487 {
488  MMSContext *mms = &mmst->mms;
490  insert_command_prefixes(mms, 1, 0x0001FFFF);
491  bytestream_put_le64(&mms->write_out_ptr, 0); // seek timestamp
492  bytestream_put_le32(&mms->write_out_ptr, 0xffffffff); // unknown
493  bytestream_put_le32(&mms->write_out_ptr, 0xffffffff); // packet offset
494  bytestream_put_byte(&mms->write_out_ptr, 0xff); // max stream time limit
495  bytestream_put_byte(&mms->write_out_ptr, 0xff); // max stream time limit
496  bytestream_put_byte(&mms->write_out_ptr, 0xff); // max stream time limit
497  bytestream_put_byte(&mms->write_out_ptr, 0x00); // stream time limit flag
498 
499  mmst->packet_id++; // new packet_id
500  bytestream_put_le32(&mms->write_out_ptr, mmst->packet_id);
501  return send_command_packet(mmst);
502 }
503 
504 
506 {
507  mms->remaining_in_len = 0;
508  mms->read_in_ptr = mms->in_buffer;
509 }
510 
511 static int mms_open(URLContext *h, const char *uri, int flags)
512 {
513  MMSTContext *mmst = h->priv_data;
514  MMSContext *mms;
515  int port, err;
516  char tcpname[256];
517 
518  h->is_streamed = 1;
519  mms = &mmst->mms;
520 
521  // only for MMS over TCP, so set proto = NULL
522  av_url_split(NULL, 0, NULL, 0,
523  mmst->host, sizeof(mmst->host), &port, mmst->path,
524  sizeof(mmst->path), uri);
525 
526  if(port<0)
527  port = 1755; // default MMS protocol port
528 
529  // establish tcp connection.
530  ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mmst->host, port, NULL);
531  err = ffurl_open_whitelist(&mms->mms_hd, tcpname, AVIO_FLAG_READ_WRITE,
532  &h->interrupt_callback, NULL,
533  h->protocol_whitelist, h->protocol_blacklist, h);
534  if (err)
535  goto fail;
536 
537  mmst->packet_id = 3; // default, initial value.
538  mmst->header_packet_id = 2; // default, initial value.
540  if (err)
541  goto fail;
543  if (err)
544  goto fail;
546  if (err)
547  goto fail;
549  if (err)
550  goto fail;
552  if (err)
553  goto fail;
555  if (err)
556  goto fail;
557  if((mmst->incoming_flags != 0X08) && (mmst->incoming_flags != 0X0C)) {
559  "The server does not support MMST (try MMSH or RTSP)\n");
560  err = AVERROR(EINVAL);
561  goto fail;
562  }
563  err = ff_mms_asf_header_parser(mms);
564  if (err) {
565  av_log(h, AV_LOG_TRACE, "asf header parsed failed!\n");
566  goto fail;
567  }
568  mms->header_parsed = 1;
569 
570  if (!mms->asf_packet_len || !mms->stream_num)
571  goto fail;
572 
575  if (err)
576  goto fail;
577  // send media packet request
579  if (err) {
580  goto fail;
581  }
582  av_log(h, AV_LOG_TRACE, "Leaving open (success)\n");
583  return 0;
584 fail:
585  mms_close(h);
586  av_log(mms->mms_hd, AV_LOG_TRACE, "Leaving open (failure: %d)\n", err);
587  return err;
588 }
589 
590 /** Read ASF data through the protocol. */
591 static int mms_read(URLContext *h, uint8_t *buf, int size)
592 {
593  /* TODO: see tcp.c:tcp_read() about a possible timeout scheme */
594  MMSTContext *mmst = h->priv_data;
595  MMSContext *mms = &mmst->mms;
596  int result = 0;
597 
598  do {
599  if(mms->asf_header_read_size < mms->asf_header_size) {
600  /* Read from ASF header buffer */
601  result = ff_mms_read_header(mms, buf, size);
602  } else if(mms->remaining_in_len) {
603  /* Read remaining packet data to buffer.
604  * the result can not be zero because remaining_in_len is positive.*/
605  result = ff_mms_read_data(mms, buf, size);
606  } else {
607  /* Read from network */
608  int err = mms_safe_send_recv(mmst, NULL, SC_PKT_ASF_MEDIA);
609  if (err == 0) {
610  if(mms->remaining_in_len>mms->asf_packet_len) {
612  "Incoming pktlen %d is larger than ASF pktsize %d\n",
613  mms->remaining_in_len, mms->asf_packet_len);
614  result= AVERROR(EIO);
615  } else {
616  // copy the data to the packet buffer.
617  result = ff_mms_read_data(mms, buf, size);
618  if (result == 0) {
619  av_log(h, AV_LOG_TRACE, "Read ASF media packet size is zero!\n");
620  break;
621  }
622  }
623  } else {
624  av_log(h, AV_LOG_TRACE, "read packet error!\n");
625  break;
626  }
627  }
628  } while(!result); // only return one packet.
629  return result;
630 }
631 
633  .name = "mmst",
634  .url_open = mms_open,
635  .url_read = mms_read,
636  .url_close = mms_close,
637  .priv_data_size = sizeof(MMSTContext),
639 };
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
URL_PROTOCOL_FLAG_NETWORK
#define URL_PROTOCOL_FLAG_NETWORK
Definition: url.h:33
AVIO_FLAG_READ_WRITE
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
Definition: avio.h:619
SC_PKT_CLIENT_ACCEPTED
@ SC_PKT_CLIENT_ACCEPTED
Control packets.
Definition: mmst.c:61
MMSCSPacketType
MMSCSPacketType
Client to server packet types.
Definition: mmst.c:43
ffurl_write
static int ffurl_write(URLContext *h, const uint8_t *buf, int size)
Write size bytes from buf to the resource accessed by h.
Definition: url.h:202
MMSContext::header_parsed
int header_parsed
The header has been received and parsed.
Definition: mms.h:51
mms_close
static int mms_close(URLContext *h)
Close the MMSH/MMST connection.
Definition: mmst.c:470
handle_packet_stream_changing_type
static void handle_packet_stream_changing_type(MMSTContext *mmst)
Definition: mmst.c:215
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
SC_PKT_PROTOCOL_FAILED
@ SC_PKT_PROTOCOL_FAILED
Definition: mmst.c:63
MMSContext::asf_header
uint8_t * asf_header
Internal handling of the ASF header.
Definition: mms.h:49
MMSTContext::incoming_flags
int incoming_flags
Incoming packet flags.
Definition: mmst.c:94
SC_PKT_STREAM_ID_ACCEPTED
@ SC_PKT_STREAM_ID_ACCEPTED
Definition: mmst.c:72
MMSSCPacketType
MMSSCPacketType
Server to client packet types.
Definition: mmst.c:58
MMSContext::asf_packet_len
int asf_packet_len
Definition: mms.h:52
MMSTContext::path
char path[256]
Path of the resource being asked for.
Definition: mmst.c:91
URLProtocol
Definition: url.h:51
CS_PKT_STREAM_PAUSE
@ CS_PKT_STREAM_PAUSE
Definition: mmst.c:48
FFIOContext
Definition: avio_internal.h:28
send_media_file_request
static int send_media_file_request(MMSTContext *mmst)
Definition: mmst.c:201
MMSContext::stream_num
int stream_num
stream numbers.
Definition: mms.h:56
AVUNERROR
#define AVUNERROR(e)
Definition: error.h:46
fail
#define fail()
Definition: checkasm.h:193
mms.h
MMSContext
Definition: mms.h:30
mms_read
static int mms_read(URLContext *h, uint8_t *buf, int size)
Read ASF data through the protocol.
Definition: mmst.c:591
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
MMSTContext::incoming_packet_seq
int incoming_packet_seq
Incoming packet sequence number.
Definition: mmst.c:93
send_stream_selection_request
static int send_stream_selection_request(MMSTContext *mmst)
Send MMST stream selection command based on the AVStream->discard values.
Definition: mmst.c:446
LOCAL_PORT
#define LOCAL_PORT
Definition: mmst.c:41
SC_PKT_MEDIA_PKT_FOLLOWS
@ SC_PKT_MEDIA_PKT_FOLLOWS
Definition: mmst.c:64
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:235
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
ff_mms_asf_header_parser
int ff_mms_asf_header_parser(MMSContext *mms)
Definition: mms.c:55
ffurl_open_whitelist
int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist, const char *blacklist, URLContext *parent)
Create an URLContext for accessing to the resource indicated by url, and open it.
Definition: avio.c:362
intreadwrite.h
SC_PKT_ASF_HEADER
@ SC_PKT_ASF_HEADER
Data packets.
Definition: mmst.c:83
MMSTContext::mms
MMSContext mms
Definition: mmst.c:89
ff_mms_read_header
int ff_mms_read_header(MMSContext *mms, uint8_t *buf, const int size)
Definition: mms.c:30
ff_url_join
int ff_url_join(char *str, int size, const char *proto, const char *authorization, const char *hostname, int port, const char *fmt,...)
Definition: url.c:40
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:94
pad_media_packet
static void pad_media_packet(MMSContext *mms)
Pad media packets smaller than max_packet_size and/or adjust read position after a seek.
Definition: mmst.c:235
MMSContext::asf_header_read_size
int asf_header_read_size
Definition: mms.h:53
MMSContext::in_buffer
uint8_t in_buffer[65536]
Buffer for incoming packets.
Definition: mms.h:42
send_media_packet_request
static int send_media_packet_request(MMSTContext *mmst)
Definition: mmst.c:486
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
NULL
#define NULL
Definition: coverity.c:32
MMSTContext::host
char host[128]
Host of the resources.
Definition: mmst.c:92
MMSContext::out_buffer
uint8_t out_buffer[512]
Buffer for outgoing packet.
Definition: mms.h:37
CS_PKT_MEDIA_HEADER_REQUEST
@ CS_PKT_MEDIA_HEADER_REQUEST
Definition: mmst.c:50
mms_put_utf16
static int mms_put_utf16(MMSContext *mms, const uint8_t *src)
Definition: mmst.c:155
MMSStream::id
int id
Definition: mms.h:27
SC_PKT_NO_DATA
@ SC_PKT_NO_DATA
Definition: mmst.c:78
ff_mms_read_data
int ff_mms_read_data(MMSContext *mms, uint8_t *buf, const int size)
Definition: mms.c:45
get_tcp_server_response
static MMSSCPacketType get_tcp_server_response(MMSTContext *mmst)
Read incoming MMST media, header or command packet.
Definition: mmst.c:245
MMSTContext::outgoing_packet_seq
int outgoing_packet_seq
Outgoing packet sequence number.
Definition: mmst.c:90
SC_PKT_MEDIA_FILE_DETAILS
@ SC_PKT_MEDIA_FILE_DETAILS
Definition: mmst.c:65
MMSContext::remaining_in_len
int remaining_in_len
Reading length from incoming buffer.
Definition: mms.h:44
FFIOContext::pub
AVIOContext pub
Definition: avio_internal.h:29
SC_PKT_PROTOCOL_ACCEPTED
@ SC_PKT_PROTOCOL_ACCEPTED
Definition: mmst.c:62
size
int size
Definition: twinvq_data.h:10344
av_reallocp
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition: mem.c:188
URLProtocol::name
const char * name
Definition: url.h:52
MMSContext::write_out_ptr
uint8_t * write_out_ptr
Buffer for outgoing packets.
Definition: mms.h:36
mms_open
static int mms_open(URLContext *h, const char *uri, int flags)
Definition: mmst.c:511
CS_PKT_MEDIA_FILE_REQUEST
@ CS_PKT_MEDIA_FILE_REQUEST
Definition: mmst.c:46
SC_PKT_HEADER_REQUEST_ACCEPTED
@ SC_PKT_HEADER_REQUEST_ACCEPTED
Definition: mmst.c:66
URLContext
Definition: url.h:35
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
avio_internal.h
CS_PKT_KEEPALIVE
@ CS_PKT_KEEPALIVE
Definition: mmst.c:53
CS_PKT_PROTOCOL_SELECT
@ CS_PKT_PROTOCOL_SELECT
Definition: mmst.c:45
SC_PKT_STREAM_STOPPED
@ SC_PKT_STREAM_STOPPED
Definition: mmst.c:70
send_command_packet
static int send_command_packet(MMSTContext *mmst)
Send a prepared MMST command packet.
Definition: mmst.c:126
send_protocol_select
static int send_protocol_select(MMSTContext *mmst)
Definition: mmst.c:177
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:351
url.h
mms_safe_send_recv
static int mms_safe_send_recv(MMSTContext *mmst, int(*send_fun)(MMSTContext *mmst), const MMSSCPacketType expect_type)
Definition: mmst.c:379
len
int len
Definition: vorbis_enc_data.h:426
start_command_packet
static void start_command_packet(MMSTContext *mmst, MMSCSPacketType packet_type)
Create MMST command packet header.
Definition: mmst.c:100
send_close_packet
static int send_close_packet(MMSTContext *mmst)
Definition: mmst.c:461
CS_PKT_START_FROM_PKT_ID
@ CS_PKT_START_FROM_PKT_ID
Definition: mmst.c:47
ffurl_closep
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
Definition: avio.c:588
ret
ret
Definition: filter_design.txt:187
MMSTContext::packet_id
int packet_id
Identifier for packets in the current stream.
Definition: mmst.c:95
CS_PKT_INITIAL
@ CS_PKT_INITIAL
Definition: mmst.c:44
avformat.h
network.h
SC_PKT_ASF_MEDIA
@ SC_PKT_ASF_MEDIA
Definition: mmst.c:84
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
SIZE_SPECIFIER
#define SIZE_SPECIFIER
Definition: internal.h:129
send_keepalive_packet
static int send_keepalive_packet(MMSTContext *mmst)
Definition: mmst.c:225
ffio_init_write_context
void ffio_init_write_context(FFIOContext *s, uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for writing.
Definition: aviobuf.c:104
CS_PKT_TIMING_DATA_REQUEST
@ CS_PKT_TIMING_DATA_REQUEST
Definition: mmst.c:51
send_media_header_request
static int send_media_header_request(MMSTContext *mmst)
Definition: mmst.c:402
LOCAL_ADDRESS
#define LOCAL_ADDRESS
Definition: mmst.c:40
clear_stream_buffers
static void clear_stream_buffers(MMSContext *mms)
Definition: mmst.c:505
MMSContext::asf_header_size
int asf_header_size
Size of stored ASF header.
Definition: mms.h:50
CS_PKT_STREAM_CLOSE
@ CS_PKT_STREAM_CLOSE
Definition: mmst.c:49
SC_PKT_TIMING_TEST_REPLY
@ SC_PKT_TIMING_TEST_REPLY
Definition: mmst.c:67
MMSTContext
Definition: mmst.c:88
mem.h
MMSTContext::header_packet_id
unsigned int header_packet_id
default is 2.
Definition: mmst.c:96
SC_PKT_PASSWORD_REQUIRED
@ SC_PKT_PASSWORD_REQUIRED
Definition: mmst.c:68
ffurl_read_complete
int ffurl_read_complete(URLContext *h, unsigned char *buf, int size)
Read as many bytes as possible (up to size), calling the read function multiple times if necessary.
Definition: avio.c:557
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
SC_PKT_STREAM_CHANGING
@ SC_PKT_STREAM_CHANGING
Definition: mmst.c:71
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
send_time_test_data
static int send_time_test_data(MMSTContext *mmst)
Definition: mmst.c:170
SC_PKT_KEEPALIVE
@ SC_PKT_KEEPALIVE
Definition: mmst.c:69
avio_put_str16le
int avio_put_str16le(AVIOContext *s, const char *str)
Convert an UTF-8 string to UTF-16LE and write it.
bytestream.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
CS_PKT_USER_PASSWORD
@ CS_PKT_USER_PASSWORD
Definition: mmst.c:52
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
h
h
Definition: vp9dsp_template.c:2070
send_startup_packet
static int send_startup_packet(MMSTContext *mmst)
Send the initial handshake.
Definition: mmst.c:424
insert_command_prefixes
static void insert_command_prefixes(MMSContext *mms, uint32_t prefix1, uint32_t prefix2)
Add prefixes to MMST command packet.
Definition: mmst.c:118
ff_mmst_protocol
const URLProtocol ff_mmst_protocol
Definition: mmst.c:632
MMSContext::mms_hd
URLContext * mms_hd
TCP connection handle.
Definition: mms.h:31
snprintf
#define snprintf
Definition: snprintf.h:34
MMSContext::streams
MMSStream * streams
Definition: mms.h:32
src
#define src
Definition: vp8dsp.c:248
MMSContext::read_in_ptr
uint8_t * read_in_ptr
Pointer for reading from incoming buffer.
Definition: mms.h:43
CS_PKT_STREAM_ID_REQUEST
@ CS_PKT_STREAM_ID_REQUEST
Definition: mmst.c:54
SC_PKT_CANCEL
@ SC_PKT_CANCEL
Pseudo packets.
Definition: mmst.c:77