FFmpeg
rtspdec.c
Go to the documentation of this file.
1 /*
2  * RTSP demuxer
3  * Copyright (c) 2002 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "config_components.h"
23 
24 #include "libavutil/avstring.h"
25 #include "libavutil/avassert.h"
26 #include "libavutil/intreadwrite.h"
27 #include "libavutil/mathematics.h"
28 #include "libavutil/mem.h"
29 #include "libavutil/random_seed.h"
30 #include "libavutil/time.h"
31 #include "avformat.h"
32 #include "demux.h"
33 
34 #include "internal.h"
35 #include "network.h"
36 #include "os_support.h"
37 #include "rtpproto.h"
38 #include "rtsp.h"
39 #include "rdt.h"
40 #include "tls.h"
41 #include "url.h"
42 #include "version.h"
43 
44 static const struct RTSPStatusMessage {
46  const char *message;
47 } status_messages[] = {
48  { RTSP_STATUS_OK, "OK" },
49  { RTSP_STATUS_METHOD, "Method Not Allowed" },
50  { RTSP_STATUS_BANDWIDTH, "Not Enough Bandwidth" },
51  { RTSP_STATUS_SESSION, "Session Not Found" },
52  { RTSP_STATUS_STATE, "Method Not Valid in This State" },
53  { RTSP_STATUS_AGGREGATE, "Aggregate operation not allowed" },
54  { RTSP_STATUS_ONLY_AGGREGATE, "Only aggregate operation allowed" },
55  { RTSP_STATUS_TRANSPORT, "Unsupported transport" },
56  { RTSP_STATUS_INTERNAL, "Internal Server Error" },
57  { RTSP_STATUS_SERVICE, "Service Unavailable" },
58  { RTSP_STATUS_VERSION, "RTSP Version not supported" },
59  { 0, "NULL" }
60 };
61 
63 {
64  RTSPState *rt = s->priv_data;
65 
66  if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN))
67  ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
68 
72  rt->real_setup = NULL;
74  return 0;
75 }
76 
77 static inline int read_line(AVFormatContext *s, char *rbuf, const int rbufsize,
78  int *rbuflen)
79 {
80  RTSPState *rt = s->priv_data;
81  int idx = 0;
82  int ret = 0;
83  *rbuflen = 0;
84 
85  do {
86  ret = ffurl_read_complete(rt->rtsp_hd, rbuf + idx, 1);
87  if (ret <= 0)
88  return ret ? ret : AVERROR_EOF;
89  if (rbuf[idx] == '\r') {
90  /* Ignore */
91  } else if (rbuf[idx] == '\n') {
92  rbuf[idx] = '\0';
93  *rbuflen = idx;
94  return 0;
95  } else
96  idx++;
97  } while (idx < rbufsize);
98  av_log(s, AV_LOG_ERROR, "Message too long\n");
99  return AVERROR(EIO);
100 }
101 
103  const char *extracontent, uint16_t seq)
104 {
105  RTSPState *rt = s->priv_data;
106  char message[MAX_URL_SIZE];
107  int index = 0;
108  while (status_messages[index].code) {
109  if (status_messages[index].code == code) {
110  snprintf(message, sizeof(message), "RTSP/1.0 %d %s\r\n",
112  break;
113  }
114  index++;
115  }
116  if (!status_messages[index].code)
117  return AVERROR(EINVAL);
118  av_strlcatf(message, sizeof(message), "CSeq: %d\r\n", seq);
119  av_strlcatf(message, sizeof(message), "Server: %s\r\n", LIBAVFORMAT_IDENT);
120  if (extracontent)
121  av_strlcat(message, extracontent, sizeof(message));
122  av_strlcat(message, "\r\n", sizeof(message));
123  av_log(s, AV_LOG_TRACE, "Sending response:\n%s", message);
124  ffurl_write(rt->rtsp_hd_out, message, strlen(message));
125 
126  return 0;
127 }
128 
129 static inline int check_sessionid(AVFormatContext *s,
130  RTSPMessageHeader *request)
131 {
132  RTSPState *rt = s->priv_data;
133  unsigned char *session_id = rt->session_id;
134  if (!session_id[0]) {
135  av_log(s, AV_LOG_WARNING, "There is no session-id at the moment\n");
136  return 0;
137  }
138  if (strcmp(session_id, request->session_id)) {
139  av_log(s, AV_LOG_ERROR, "Unexpected session-id %s\n",
140  request->session_id);
143  }
144  return 0;
145 }
146 
148  RTSPMessageHeader *request,
149  const char *method)
150 {
151  RTSPState *rt = s->priv_data;
152  char rbuf[MAX_URL_SIZE];
153  int rbuflen, ret;
154  do {
155  ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
156  if (ret)
157  return ret;
158  if (rbuflen > 1) {
159  av_log(s, AV_LOG_TRACE, "Parsing[%d]: %s\n", rbuflen, rbuf);
160  ff_rtsp_parse_line(s, request, rbuf, rt, method);
161  }
162  } while (rbuflen > 0);
163  if (request->seq != rt->seq + 1) {
164  av_log(s, AV_LOG_ERROR, "Unexpected Sequence number %d\n",
165  request->seq);
166  return AVERROR(EINVAL);
167  }
168  if (rt->session_id[0] && strcmp(method, "OPTIONS")) {
169  ret = check_sessionid(s, request);
170  if (ret)
171  return ret;
172  }
173 
174  return 0;
175 }
176 
178 {
179  RTSPState *rt = s->priv_data;
180  RTSPMessageHeader request = { 0 };
181  char *sdp;
182  int ret;
183 
184  ret = rtsp_read_request(s, &request, "ANNOUNCE");
185  if (ret)
186  return ret;
187  rt->seq++;
188  if (strcmp(request.content_type, "application/sdp")) {
189  av_log(s, AV_LOG_ERROR, "Unexpected content type %s\n",
190  request.content_type);
193  }
194  if (request.content_length) {
195  sdp = av_malloc(request.content_length + 1);
196  if (!sdp)
197  return AVERROR(ENOMEM);
198 
199  /* Read SDP */
200  if (ffurl_read_complete(rt->rtsp_hd, sdp, request.content_length)
201  < request.content_length) {
203  "Unable to get complete SDP Description in ANNOUNCE\n");
205  av_free(sdp);
206  return AVERROR(EIO);
207  }
208  sdp[request.content_length] = '\0';
209  av_log(s, AV_LOG_VERBOSE, "SDP: %s\n", sdp);
210  ret = ff_sdp_parse(s, sdp);
211  av_free(sdp);
212  if (ret)
213  return ret;
215  return 0;
216  }
218  "Content-Length header value exceeds sdp allocated buffer (4KB)\n");
220  "Content-Length exceeds buffer size", request.seq);
221  return AVERROR(EIO);
222 }
223 
225 {
226  RTSPState *rt = s->priv_data;
227  RTSPMessageHeader request = { 0 };
228  int ret = 0;
229 
230  /* Parsing headers */
231  ret = rtsp_read_request(s, &request, "OPTIONS");
232  if (ret)
233  return ret;
234  rt->seq++;
235  /* Send Reply */
237  "Public: ANNOUNCE, PAUSE, SETUP, TEARDOWN, RECORD\r\n",
238  request.seq);
239  return 0;
240 }
241 
242 static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl)
243 {
244  RTSPState *rt = s->priv_data;
245  RTSPMessageHeader request = { 0 };
246  int ret = 0;
247  char url[MAX_URL_SIZE];
248  RTSPStream *rtsp_st;
249  char responseheaders[MAX_URL_SIZE];
250  int localport = -1;
251  int transportidx = 0;
252  int streamid = 0;
253 
254  ret = rtsp_read_request(s, &request, "SETUP");
255  if (ret)
256  return ret;
257  rt->seq++;
258  if (!request.nb_transports) {
259  av_log(s, AV_LOG_ERROR, "No transport defined in SETUP\n");
260  return AVERROR_INVALIDDATA;
261  }
262  for (transportidx = 0; transportidx < request.nb_transports;
263  transportidx++) {
264  if (!request.transports[transportidx].mode_record ||
265  (request.transports[transportidx].lower_transport !=
267  request.transports[transportidx].lower_transport !=
269  av_log(s, AV_LOG_ERROR, "mode=record/receive not set or transport"
270  " protocol not supported (yet)\n");
271  return AVERROR_INVALIDDATA;
272  }
273  }
274  if (request.nb_transports > 1)
275  av_log(s, AV_LOG_WARNING, "More than one transport not supported, "
276  "using first of all\n");
277  for (streamid = 0; streamid < rt->nb_rtsp_streams; streamid++) {
278  if (!strcmp(rt->rtsp_streams[streamid]->control_url,
279  controlurl))
280  break;
281  }
282  if (streamid == rt->nb_rtsp_streams) {
283  av_log(s, AV_LOG_ERROR, "Unable to find requested track\n");
285  }
286  rtsp_st = rt->rtsp_streams[streamid];
287  localport = rt->rtp_port_min;
288 
289  /* check if the stream has already been setup */
290  if (rtsp_st->transport_priv) {
291  if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT)
293  else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP)
295  rtsp_st->transport_priv = NULL;
296  }
297  if (rtsp_st->rtp_handle)
298  ffurl_closep(&rtsp_st->rtp_handle);
299 
302  if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
304  return ret;
305  }
306  rtsp_st->interleaved_min = request.transports[0].interleaved_min;
307  rtsp_st->interleaved_max = request.transports[0].interleaved_max;
308  snprintf(responseheaders, sizeof(responseheaders), "Transport: "
309  "RTP/AVP/TCP;unicast;mode=record;interleaved=%d-%d"
310  "\r\n", request.transports[0].interleaved_min,
311  request.transports[0].interleaved_max);
312  } else {
313  do {
315  av_dict_set_int(&opts, "buffer_size", rt->buffer_size, 0);
316  ff_url_join(url, sizeof(url), "rtp", NULL, host, localport, NULL);
317  av_log(s, AV_LOG_TRACE, "Opening: %s\n", url);
319  &s->interrupt_callback, &opts,
320  s->protocol_whitelist, s->protocol_blacklist, NULL);
321  av_dict_free(&opts);
322  if (ret)
323  localport += 2;
324  } while (ret || localport > rt->rtp_port_max);
325  if (localport > rt->rtp_port_max) {
327  return ret;
328  }
329 
330  av_log(s, AV_LOG_TRACE, "Listening on: %d\n",
332  if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
334  return ret;
335  }
336 
337  localport = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
338  snprintf(responseheaders, sizeof(responseheaders), "Transport: "
339  "RTP/AVP/UDP;unicast;mode=record;source=%s;"
340  "client_port=%d-%d;server_port=%d-%d\r\n",
341  host, request.transports[0].client_port_min,
342  request.transports[0].client_port_max, localport,
343  localport + 1);
344  }
345 
346  /* Establish sessionid if not previously set */
347  /* Put this in a function? */
348  /* RFC 2326: session id must be at least 8 digits */
349  while (strlen(rt->session_id) < 8)
350  av_strlcatf(rt->session_id, 512, "%u", av_get_random_seed());
351 
352  av_strlcatf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
353  rt->session_id);
354  /* Send Reply */
355  rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
356 
357  rt->state = RTSP_STATE_PAUSED;
358  return 0;
359 }
360 
362 {
363  RTSPState *rt = s->priv_data;
364  RTSPMessageHeader request = { 0 };
365  int ret = 0;
366  char responseheaders[MAX_URL_SIZE];
367 
368  ret = rtsp_read_request(s, &request, "RECORD");
369  if (ret)
370  return ret;
371  ret = check_sessionid(s, &request);
372  if (ret)
373  return ret;
374  rt->seq++;
375  snprintf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
376  rt->session_id);
377  rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
378 
380  return 0;
381 }
382 
383 static inline int parse_command_line(AVFormatContext *s, const char *line,
384  int linelen, char *uri, int urisize,
385  char *method, int methodsize,
386  enum RTSPMethod *methodcode)
387 {
388  RTSPState *rt = s->priv_data;
389  const char *linept, *searchlinept;
390  linept = strchr(line, ' ');
391 
392  if (!linept) {
393  av_log(s, AV_LOG_ERROR, "Error parsing method string\n");
394  return AVERROR_INVALIDDATA;
395  }
396 
397  if (linept - line > methodsize - 1) {
398  av_log(s, AV_LOG_ERROR, "Method string too long\n");
399  return AVERROR(EIO);
400  }
401  memcpy(method, line, linept - line);
402  method[linept - line] = '\0';
403  linept++;
404  if (!strcmp(method, "ANNOUNCE"))
405  *methodcode = ANNOUNCE;
406  else if (!strcmp(method, "OPTIONS"))
407  *methodcode = OPTIONS;
408  else if (!strcmp(method, "RECORD"))
409  *methodcode = RECORD;
410  else if (!strcmp(method, "SETUP"))
411  *methodcode = SETUP;
412  else if (!strcmp(method, "PAUSE"))
413  *methodcode = PAUSE;
414  else if (!strcmp(method, "TEARDOWN"))
415  *methodcode = TEARDOWN;
416  else
417  *methodcode = UNKNOWN;
418  /* Check method with the state */
419  if (rt->state == RTSP_STATE_IDLE) {
420  if ((*methodcode != ANNOUNCE) && (*methodcode != OPTIONS)) {
421  av_log(s, AV_LOG_ERROR, "Unexpected command in Idle State %s\n",
422  line);
424  }
425  } else if (rt->state == RTSP_STATE_PAUSED) {
426  if ((*methodcode != OPTIONS) && (*methodcode != RECORD)
427  && (*methodcode != SETUP)) {
428  av_log(s, AV_LOG_ERROR, "Unexpected command in Paused State %s\n",
429  line);
431  }
432  } else if (rt->state == RTSP_STATE_STREAMING) {
433  if ((*methodcode != PAUSE) && (*methodcode != OPTIONS)
434  && (*methodcode != TEARDOWN)) {
435  av_log(s, AV_LOG_ERROR, "Unexpected command in Streaming State"
436  " %s\n", line);
438  }
439  } else {
440  av_log(s, AV_LOG_ERROR, "Unexpected State [%d]\n", rt->state);
441  return AVERROR_BUG;
442  }
443 
444  searchlinept = strchr(linept, ' ');
445  if (!searchlinept) {
446  av_log(s, AV_LOG_ERROR, "Error parsing message URI\n");
447  return AVERROR_INVALIDDATA;
448  }
449  if (searchlinept - linept > urisize - 1) {
450  av_log(s, AV_LOG_ERROR, "uri string length exceeded buffer size\n");
451  return AVERROR(EIO);
452  }
453  memcpy(uri, linept, searchlinept - linept);
454  uri[searchlinept - linept] = '\0';
455  if (strcmp(rt->control_uri, uri)) {
456  char host[128], path[512], auth[128];
457  int port;
458  char ctl_host[128], ctl_path[512], ctl_auth[128];
459  int ctl_port;
460  av_url_split(NULL, 0, auth, sizeof(auth), host, sizeof(host), &port,
461  path, sizeof(path), uri);
462  av_url_split(NULL, 0, ctl_auth, sizeof(ctl_auth), ctl_host,
463  sizeof(ctl_host), &ctl_port, ctl_path, sizeof(ctl_path),
464  rt->control_uri);
465  if (strcmp(host, ctl_host))
466  av_log(s, AV_LOG_INFO, "Host %s differs from expected %s\n",
467  host, ctl_host);
468  if (strcmp(path, ctl_path) && *methodcode != SETUP)
469  av_log(s, AV_LOG_WARNING, "WARNING: Path %s differs from expected"
470  " %s\n", path, ctl_path);
471  if (*methodcode == ANNOUNCE) {
473  "Updating control URI to %s\n", uri);
474  av_strlcpy(rt->control_uri, uri, sizeof(rt->control_uri));
475  }
476  }
477 
478  linept = searchlinept + 1;
479  if (!av_strstart(linept, "RTSP/1.0", NULL)) {
480  av_log(s, AV_LOG_ERROR, "Error parsing protocol or version\n");
482  }
483  return 0;
484 }
485 
487 {
488  RTSPState *rt = s->priv_data;
489  unsigned char rbuf[MAX_URL_SIZE];
490  unsigned char method[10];
491  char uri[500];
492  int ret;
493  int rbuflen = 0;
494  RTSPMessageHeader request = { 0 };
495  enum RTSPMethod methodcode;
496 
497  ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
498  if (ret < 0)
499  return ret;
500  av_log(s, AV_LOG_TRACE, "Parsing[%d]: %s\n", rbuflen, rbuf);
501  ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
502  sizeof(method), &methodcode);
503  if (ret) {
504  av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
505  return ret;
506  }
507 
508  ret = rtsp_read_request(s, &request, method);
509  if (ret)
510  return ret;
511  rt->seq++;
512  if (methodcode == PAUSE) {
513  rt->state = RTSP_STATE_PAUSED;
514  ret = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
515  // TODO: Missing date header in response
516  } else if (methodcode == OPTIONS) {
518  "Public: ANNOUNCE, PAUSE, SETUP, TEARDOWN, "
519  "RECORD\r\n", request.seq);
520  } else if (methodcode == TEARDOWN) {
521  rt->state = RTSP_STATE_IDLE;
522  ret = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
523  }
524  return ret;
525 }
526 
528 {
529  RTSPState *rt = s->priv_data;
530  RTSPMessageHeader reply1, *reply = &reply1;
531  int i;
532  char cmd[MAX_URL_SIZE];
533 
534  av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
535  rt->nb_byes = 0;
536 
538  for (i = 0; i < rt->nb_rtsp_streams; i++) {
539  RTSPStream *rtsp_st = rt->rtsp_streams[i];
540  /* Try to initialize the connection state in a
541  * potential NAT router by sending dummy packets.
542  * RTP/RTCP dummy packets are used for RDT, too.
543  */
544  if (rtsp_st->rtp_handle &&
545  !(rt->server_type == RTSP_SERVER_WMS && i > 1))
547  }
548  }
549  if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
550  if (rt->transport == RTSP_TRANSPORT_RTP) {
551  for (i = 0; i < rt->nb_rtsp_streams; i++) {
552  RTSPStream *rtsp_st = rt->rtsp_streams[i];
553  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
554  if (!rtpctx)
555  continue;
559  rtpctx->base_timestamp = 0;
560  rtpctx->timestamp = 0;
561  rtpctx->unwrapped_timestamp = 0;
562  rtpctx->rtcp_ts_offset = 0;
563  }
564  }
565  if (rt->state == RTSP_STATE_PAUSED) {
566  cmd[0] = 0;
567  } else {
568  snprintf(cmd, sizeof(cmd),
569  "Range: npt=%"PRId64".%03"PRId64"-\r\n",
571  rt->seek_timestamp / (AV_TIME_BASE / 1000) % 1000);
572  }
573  ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL);
574  if (reply->status_code != RTSP_STATUS_OK) {
575  return ff_rtsp_averror(reply->status_code, -1);
576  }
577  if (rt->transport == RTSP_TRANSPORT_RTP &&
578  reply->range_start != AV_NOPTS_VALUE) {
579  for (i = 0; i < rt->nb_rtsp_streams; i++) {
580  RTSPStream *rtsp_st = rt->rtsp_streams[i];
581  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
582  AVStream *st = NULL;
583  if (!rtpctx || rtsp_st->stream_index < 0)
584  continue;
585 
586  st = s->streams[rtsp_st->stream_index];
587  rtpctx->range_start_offset =
589  st->time_base);
590  }
591  }
592  }
594  return 0;
595 }
596 
597 /* pause the stream */
599 {
600  RTSPState *rt = s->priv_data;
601  RTSPMessageHeader reply1, *reply = &reply1;
602 
603  if (rt->state != RTSP_STATE_STREAMING)
604  return 0;
605  else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
606  ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL);
607  if (reply->status_code != RTSP_STATUS_OK) {
608  return ff_rtsp_averror(reply->status_code, -1);
609  }
610  }
611  rt->state = RTSP_STATE_PAUSED;
612  return 0;
613 }
614 
617 {
618  switch (state) {
619  case FF_INFMT_STATE_PLAY:
620  return rtsp_read_play(s);
622  return rtsp_read_pause(s);
623  default:
624  return AVERROR(ENOTSUP);
625  }
626 }
627 
629 {
630  char *buf;
631  AVBPrint bprint;
633 
634  const AVDictionaryEntry *header = NULL;
635  while ((header = av_dict_iterate(headers, header))) {
636  av_bprintf(&bprint, "%s: %s\r\n", header->key, header->value);
637  }
638 
639  av_bprint_finalize(&bprint, &buf);
640  return buf;
641 }
642 
643 static int rtsp_submit_command(struct AVFormatContext *s, enum AVFormatCommandID id, void *data)
644 {
646  return AVERROR(ENOTSUP);
647  if (!data)
648  return AVERROR(EINVAL);
649 
650  RTSPState *rt = s->priv_data;
651  AVRTSPCommandRequest *req = data;
652 
653  if (rt->state == RTSP_STATE_IDLE)
654  // Not ready to send a SET_PARAMETERS command yet
655  return AVERROR(EAGAIN);
656 
657  av_log(s, AV_LOG_DEBUG, "Sending SET_PARAMETER command to %s\n", rt->control_uri);
658  char *headers = dict_to_headers(req->headers);
659 
660  int ret = ff_rtsp_send_cmd_with_content_async_stored(s, "SET_PARAMETER",
661  rt->control_uri, headers, req->body, req->body_len);
662  av_free(headers);
663 
664  if (ret != 0)
665  av_log(s, AV_LOG_ERROR, "Failure sending SET_PARAMETER command: %s\n", av_err2str(ret));
666 
667  return ret;
668 }
669 
670 static int rtsp_read_command_reply(AVFormatContext *s, enum AVFormatCommandID id, void **data_out)
671 {
673  return AVERROR(ENOTSUP);
674  if (!data_out)
675  return AVERROR(EINVAL);
676 
677  AVRTSPResponse *res = av_malloc(sizeof(*res));
678  if (!res)
679  return AVERROR(ENOMEM);
680 
681  RTSPMessageHeader *reply;
682  int ret = ff_rtsp_read_reply_async_stored(s, &reply, &res->body);
683  if (ret < 0)
684  return ret;
685 
686  res->status_code = reply->status_code;
687  res->body_len = reply->content_length;
688 
689  res->reason = av_strdup(reply->reason);
690  if (!res->reason) {
691  av_free(res->body);
692  av_free(res);
693  av_free(reply);
694  return AVERROR(ENOMEM);
695  }
696 
697  *data_out = res;
698  return 0;
699 }
700 
703  enum AVFormatCommandID id, void *data)
704 {
705  switch (opt) {
707  return rtsp_submit_command(s, id, data);
709  return rtsp_read_command_reply(s, id, data);
710  default:
711  av_unreachable("Invalid command option");
712  }
713 }
714 
716 {
717  RTSPState *rt = s->priv_data;
718  char cmd[MAX_URL_SIZE];
719  unsigned char *content = NULL;
720  int ret;
721 
722  /* describe the stream */
723  snprintf(cmd, sizeof(cmd),
724  "Accept: application/sdp\r\n");
725  if (rt->server_type == RTSP_SERVER_REAL) {
726  /**
727  * The Require: attribute is needed for proper streaming from
728  * Realmedia servers.
729  */
730  av_strlcat(cmd,
731  "Require: com.real.retain-entity-for-setup\r\n",
732  sizeof(cmd));
733  }
734  ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content);
735  if (reply->status_code != RTSP_STATUS_OK) {
736  av_freep(&content);
738  }
739  if (!content)
740  return AVERROR_INVALIDDATA;
741 
742  av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content);
743  /* now we got the SDP description, we parse it */
744  ret = ff_sdp_parse(s, (const char *)content);
745  av_freep(&content);
746  if (ret < 0)
747  return ret;
748 
749  return 0;
750 }
751 
753 {
754  RTSPState *rt = s->priv_data;
755  char proto[128], host[128], path[512], auth[128];
756  char uri[500];
757  int port;
758  int default_port = RTSP_DEFAULT_PORT;
759  char tcpname[500];
760  const char *lower_proto = "tcp";
761  unsigned char rbuf[MAX_URL_SIZE];
762  unsigned char method[10];
763  int rbuflen = 0;
764  int ret;
765  enum RTSPMethod methodcode;
766 
767  if (!ff_network_init())
768  return AVERROR(EIO);
769 
770  /* extract hostname and port */
771  av_url_split(proto, sizeof(proto), auth, sizeof(auth), host, sizeof(host),
772  &port, path, sizeof(path), s->url);
773 
774  /* ff_url_join. No authorization by now (NULL) */
775  ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL, host,
776  port, "%s", path);
777 
778  if (!strcmp(proto, "rtsps")) {
779  lower_proto = "tls";
780  default_port = RTSPS_DEFAULT_PORT;
781  }
782 
783  if (port < 0)
784  port = default_port;
785 
786  /* Create TCP connection */
787  ff_url_join(tcpname, sizeof(tcpname), lower_proto, NULL, host, port,
788  "?listen&listen_timeout=%d", rt->initial_timeout * 1000);
789 
791  &s->interrupt_callback, NULL,
792  s->protocol_whitelist, s->protocol_blacklist, NULL)) {
793  av_log(s, AV_LOG_ERROR, "Unable to open RTSP for listening\n");
794  goto fail;
795  }
796  rt->state = RTSP_STATE_IDLE;
797  rt->rtsp_hd_out = rt->rtsp_hd;
798  for (;;) { /* Wait for incoming RTSP messages */
799  ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
800  if (ret < 0)
801  goto fail;
802  av_log(s, AV_LOG_TRACE, "Parsing[%d]: %s\n", rbuflen, rbuf);
803  ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
804  sizeof(method), &methodcode);
805  if (ret) {
806  av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
807  goto fail;
808  }
809 
810  if (methodcode == ANNOUNCE) {
812  rt->state = RTSP_STATE_PAUSED;
813  } else if (methodcode == OPTIONS) {
815  } else if (methodcode == RECORD) {
817  if (!ret)
818  return 0; // We are ready for streaming
819  } else if (methodcode == SETUP)
820  ret = rtsp_read_setup(s, host, uri);
821  if (ret) {
823  goto fail;
824  }
825  }
826 fail:
830  return ret;
831 }
832 
833 static int rtsp_probe(const AVProbeData *p)
834 {
835  if (
836 #if CONFIG_TLS_PROTOCOL
837  av_strstart(p->filename, "rtsps:", NULL) ||
838 #endif
839  av_strstart(p->filename, "satip:", NULL) ||
840  av_strstart(p->filename, "rtsp:", NULL))
841  return AVPROBE_SCORE_MAX;
842  return 0;
843 }
844 
846 {
847  RTSPState *rt = s->priv_data;
848  int ret;
849 
850  if (rt->initial_timeout > 0)
852 
853  if (rt->rtsp_flags & RTSP_FLAG_LISTEN) {
854  ret = rtsp_listen(s);
855  if (ret)
856  return ret;
857  } else {
858  ret = ff_rtsp_connect(s);
859  if (ret)
860  return ret;
861 
862  rt->real_setup_cache = !s->nb_streams ? NULL :
863  av_calloc(s->nb_streams, 2 * sizeof(*rt->real_setup_cache));
864  if (!rt->real_setup_cache && s->nb_streams) {
865  ret = AVERROR(ENOMEM);
866  goto fail;
867  }
868  rt->real_setup = rt->real_setup_cache + s->nb_streams;
869 
870  if (rt->initial_pause) {
871  /* do not start immediately */
872  } else {
873  ret = rtsp_read_play(s);
874  if (ret < 0)
875  goto fail;
876  }
877  }
878 
879  return 0;
880 
881 fail:
883  return ret;
884 }
885 
887  uint8_t *buf, int buf_size)
888 {
889  RTSPState *rt = s->priv_data;
890  int id, len, i, ret;
891  RTSPStream *rtsp_st;
892 
893  av_log(s, AV_LOG_TRACE, "tcp_read_packet:\n");
894 redo:
895  for (;;) {
896  RTSPMessageHeader reply;
897 
898  ret = ff_rtsp_read_reply(s, &reply, NULL, 1, NULL);
899  if (ret < 0)
900  return ret;
901  if (ret == 1) /* received '$' */
902  break;
903  /* XXX: parse message */
904  if (rt->state != RTSP_STATE_STREAMING)
905  return 0;
906  }
907  ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
908  if (ret != 3)
909  return AVERROR(EIO);
910  rt->pending_packet = 0;
911  id = buf[0];
912  len = AV_RB16(buf + 1);
913  av_log(s, AV_LOG_TRACE, "id=%d len=%d\n", id, len);
914  if (len > buf_size || len < 8)
915  goto redo;
916  /* get the data */
917  ret = ffurl_read_complete(rt->rtsp_hd, buf, len);
918  if (ret != len)
919  return AVERROR(EIO);
920  if (rt->transport == RTSP_TRANSPORT_RDT &&
921  (ret = ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL)) < 0)
922  return ret;
923 
924  /* find the matching stream */
925  for (i = 0; i < rt->nb_rtsp_streams; i++) {
926  rtsp_st = rt->rtsp_streams[i];
927  if (id >= rtsp_st->interleaved_min &&
928  id <= rtsp_st->interleaved_max)
929  goto found;
930  }
931  goto redo;
932 found:
933  *prtsp_st = rtsp_st;
934  return len;
935 }
936 
938 {
939  RTSPState *rt = s->priv_data;
940  char host[1024];
941  int port;
942 
943  av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0,
944  s->url);
945  ff_rtsp_undo_setup(s, 0);
947  rt->real_challenge);
948 }
949 
951 {
952  RTSPState *rt = s->priv_data;
953  int ret;
954  RTSPMessageHeader reply1, *reply = &reply1;
955  char cmd[MAX_URL_SIZE];
956 
957 retry:
958  if (rt->server_type == RTSP_SERVER_REAL) {
959  int i;
960 
961  for (i = 0; i < s->nb_streams; i++)
962  rt->real_setup[i] = s->streams[i]->discard;
963 
964  if (!rt->need_subscription) {
965  if (memcmp (rt->real_setup, rt->real_setup_cache,
966  sizeof(enum AVDiscard) * s->nb_streams)) {
967  snprintf(cmd, sizeof(cmd),
968  "Unsubscribe: %s\r\n",
969  rt->last_subscription);
970  ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
971  cmd, reply, NULL);
972  if (reply->status_code != RTSP_STATUS_OK)
974  rt->need_subscription = 1;
975  }
976  }
977 
978  if (rt->need_subscription) {
979  int r, rule_nr, first = 1;
980 
981  memcpy(rt->real_setup_cache, rt->real_setup,
982  sizeof(enum AVDiscard) * s->nb_streams);
983  rt->last_subscription[0] = 0;
984 
985  snprintf(cmd, sizeof(cmd),
986  "Subscribe: ");
987  for (i = 0; i < rt->nb_rtsp_streams; i++) {
988  rule_nr = 0;
989  for (r = 0; r < s->nb_streams; r++) {
990  if (s->streams[r]->id == i) {
991  if (s->streams[r]->discard != AVDISCARD_ALL) {
992  if (!first)
993  av_strlcat(rt->last_subscription, ",",
994  sizeof(rt->last_subscription));
996  rt->last_subscription,
997  sizeof(rt->last_subscription), i, rule_nr);
998  first = 0;
999  }
1000  rule_nr++;
1001  }
1002  }
1003  }
1004  av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);
1005  ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
1006  cmd, reply, NULL);
1007  if (reply->status_code != RTSP_STATUS_OK)
1009  rt->need_subscription = 0;
1010 
1011  if (rt->state == RTSP_STATE_STREAMING)
1012  rtsp_read_play (s);
1013  }
1014  }
1015 
1017  if (ret < 0) {
1018  if (ret == AVERROR(ETIMEDOUT) && !rt->packets) {
1021  RTSPMessageHeader reply1, *reply = &reply1;
1022  av_log(s, AV_LOG_WARNING, "UDP timeout, retrying with TCP\n");
1023  if (rtsp_read_pause(s) != 0)
1024  return -1;
1025  // TEARDOWN is required on Real-RTSP, but might make
1026  // other servers close the connection.
1027  if (rt->server_type == RTSP_SERVER_REAL)
1028  ff_rtsp_send_cmd(s, "TEARDOWN", rt->control_uri, NULL,
1029  reply, NULL);
1030  rt->session_id[0] = '\0';
1031  if (resetup_tcp(s) == 0) {
1032  rt->state = RTSP_STATE_IDLE;
1033  rt->need_subscription = 1;
1034  if (rtsp_read_play(s) != 0)
1035  return -1;
1036  goto retry;
1037  }
1038  }
1039  }
1040  return ret;
1041  }
1042  rt->packets++;
1043 
1044  if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN)) {
1045  /* send dummy request to keep TCP connection alive */
1046  if ((av_gettime_relative() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2 ||
1047  rt->auth_state.stale) {
1048  if (rt->server_type == RTSP_SERVER_WMS ||
1049  (rt->server_type != RTSP_SERVER_REAL &&
1050  rt->get_parameter_supported)) {
1051  ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
1052  } else {
1053  ff_rtsp_send_cmd_async(s, "OPTIONS", rt->control_uri, NULL);
1054  }
1055  /* The stale flag should be reset when creating the auth response in
1056  * ff_rtsp_send_cmd_async, but reset it here just in case we never
1057  * called the auth code (if we didn't have any credentials set). */
1058  rt->auth_state.stale = 0;
1059  }
1060  }
1061 
1062  return 0;
1063 }
1064 
1065 static int rtsp_read_seek(AVFormatContext *s, int stream_index,
1066  int64_t timestamp, int flags)
1067 {
1068  RTSPState *rt = s->priv_data;
1069  int ret;
1070 
1071  rt->seek_timestamp = av_rescale_q(timestamp,
1072  s->streams[stream_index]->time_base,
1073  AV_TIME_BASE_Q);
1074  switch(rt->state) {
1075  default:
1076  case RTSP_STATE_IDLE:
1077  break;
1078  case RTSP_STATE_STREAMING:
1079  if ((ret = rtsp_read_pause(s)) != 0)
1080  return ret;
1081  rt->state = RTSP_STATE_SEEKING;
1082  if ((ret = rtsp_read_play(s)) != 0)
1083  return ret;
1084  break;
1085  case RTSP_STATE_PAUSED:
1086  rt->state = RTSP_STATE_IDLE;
1087  break;
1088  }
1089  return 0;
1090 }
1091 
1092 static const AVClass rtsp_demuxer_class = {
1093  .class_name = "RTSP demuxer",
1094  .item_name = av_default_item_name,
1095  .option = ff_rtsp_options,
1096  .version = LIBAVUTIL_VERSION_INT,
1097 };
1098 
1100  .p.name = "rtsp",
1101  .p.long_name = NULL_IF_CONFIG_SMALL("RTSP input"),
1102  .p.flags = AVFMT_NOFILE,
1103  .p.priv_class = &rtsp_demuxer_class,
1104  .priv_data_size = sizeof(RTSPState),
1110  .read_set_state = rtsp_read_set_state,
1111  .handle_command = rtsp_handle_command,
1112 };
flags
const SwsFlags flags[]
Definition: swscale.c:61
RTSPState::initial_timeout
int initial_timeout
Timeout to wait for incoming connections.
Definition: rtsp.h:423
RTSP_STATE_PAUSED
@ RTSP_STATE_PAUSED
initialized, but not receiving data
Definition: rtsp.h:205
ff_rdt_subscribe_rule
void ff_rdt_subscribe_rule(char *cmd, int size, int stream_nr, int rule_nr)
Add subscription information to Subscribe parameter string.
Definition: rdt.c:388
FF_INFMT_STATE_PAUSE
@ FF_INFMT_STATE_PAUSE
Definition: demux.h:53
RTSPState::initial_pause
int initial_pause
Do not begin to play the stream immediately.
Definition: rtsp.h:395
ff_rtsp_read_reply
int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply, unsigned char **content_ptr, int return_on_interleaved_data, const char *method)
Read a RTSP message from the server, or prepare to read data packets if we're reading data interleave...
RTSPState::last_cmd_time
int64_t last_cmd_time
timestamp of the last RTSP command that we sent to the RTSP server.
Definition: rtsp.h:263
av_gettime_relative
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition: time.c:56
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
ff_rtsp_close_streams
void ff_rtsp_close_streams(AVFormatContext *s)
Close and free all streams within the RTSP (de)muxer.
Definition: rtsp.c:832
LIBAVFORMAT_IDENT
#define LIBAVFORMAT_IDENT
Definition: version.h:45
AVRTCPSenderReport::ntp_timestamp
uint64_t ntp_timestamp
NTP time when the report was sent.
Definition: defs.h:347
rtsp_read_request
static int rtsp_read_request(AVFormatContext *s, RTSPMessageHeader *request, const char *method)
Definition: rtspdec.c:147
r
const char * r
Definition: vf_curves.c:127
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
RTSPStream::transport_priv
void * transport_priv
RTP/RDT parse context if input, RTP AVFormatContext if output.
Definition: rtsp.h:479
RTSPStream::rtp_handle
URLContext * rtp_handle
RTP stream handle (if UDP)
Definition: rtsp.h:478
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
message
Definition: api-threadmessage-test.c:47
RTSP_STATE_SEEKING
@ RTSP_STATE_SEEKING
initialized, requesting a seek
Definition: rtsp.h:206
RTSPMessageHeader::status_code
enum RTSPStatusCode status_code
response code from server
Definition: rtsp.h:133
ff_rtsp_send_cmd
int ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url, const char *headers, RTSPMessageHeader *reply, unsigned char **content_ptr)
Send a command to the RTSP server and wait for the reply.
resetup_tcp
static int resetup_tcp(AVFormatContext *s)
Definition: rtspdec.c:937
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AVIO_FLAG_READ_WRITE
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
Definition: avio.h:619
rtsp_read_options
static int rtsp_read_options(AVFormatContext *s)
Definition: rtspdec.c:224
RTSP_TRANSPORT_RTP
@ RTSP_TRANSPORT_RTP
Standards-compliant RTP.
Definition: rtsp.h:60
AVRTSPCommandRequest::body
char * body
Body payload.
Definition: avformat.h:2404
RTSP_STATUS_METHOD
@ RTSP_STATUS_METHOD
Definition: rtspcodes.h:47
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:263
int64_t
long long int64_t
Definition: coverity.c:34
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
RTSPState::get_parameter_supported
int get_parameter_supported
Whether the server supports the GET_PARAMETER method.
Definition: rtsp.h:390
ff_rtsp_averror
static int ff_rtsp_averror(enum RTSPStatusCode status_code, int default_averror)
Definition: rtspcodes.h:144
RTSPStream::interleaved_min
int interleaved_min
interleave IDs; copies of RTSPTransportField->interleaved_min/max for the selected transport.
Definition: rtsp.h:486
ff_rtsp_read_reply_async_stored
int ff_rtsp_read_reply_async_stored(AVFormatContext *s, RTSPMessageHeader **reply, unsigned char **content_ptr)
Retrieve a previously stored RTSP reply message from the server.
rtsp_read_setup
static int rtsp_read_setup(AVFormatContext *s, char *host, char *controlurl)
Definition: rtspdec.c:242
OPTIONS
@ OPTIONS
Definition: rtspcodes.h:132
rtsp_read_close
static int rtsp_read_close(AVFormatContext *s)
Definition: rtspdec.c:62
rtsp_send_reply
static int rtsp_send_reply(AVFormatContext *s, enum RTSPStatusCode code, const char *extracontent, uint16_t seq)
Definition: rtspdec.c:102
RTPDemuxContext::range_start_offset
int64_t range_start_offset
Definition: rtpdec.h:157
RTSPTransportField::lower_transport
enum RTSPLowerTransport lower_transport
network layer transport protocol; e.g.
Definition: rtsp.h:123
RTSPState::rtp_port_min
int rtp_port_min
Minimum and maximum local UDP ports.
Definition: rtsp.h:418
data
const char data[16]
Definition: mxf.c:149
AVRTSPCommandRequest::body_len
size_t body_len
Body payload size.
Definition: avformat.h:2399
RTSPTransportField::interleaved_min
int interleaved_min
interleave ids, if TCP transport; each TCP/RTSP data packet starts with a '$', stream length and stre...
Definition: rtsp.h:95
RTSPTransportField::interleaved_max
int interleaved_max
Definition: rtsp.h:95
RTSPStream
Describe a single stream, as identified by a single m= line block in the SDP content.
Definition: rtsp.h:477
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
UNKNOWN
@ UNKNOWN
Definition: ftp.c:39
ff_rtsp_send_cmd_async
int ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method, const char *url, const char *headers)
Send a command to the RTSP server without waiting for the reply.
RTSPState::real_challenge
char real_challenge[64]
the "RealChallenge1:" field from the server
Definition: rtsp.h:278
mathematics.h
AVDictionary
Definition: dict.c:32
ff_network_close
void ff_network_close(void)
Definition: network.c:113
RTSPMessageHeader::nb_transports
int nb_transports
number of items in the 'transports' variable below
Definition: rtsp.h:136
RTSP_SERVER_REAL
@ RTSP_SERVER_REAL
Realmedia-style server.
Definition: rtsp.h:215
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
RTSPState::seek_timestamp
int64_t seek_timestamp
the seek value requested when calling av_seek_frame().
Definition: rtsp.h:247
ANNOUNCE
@ ANNOUNCE
Definition: rtspcodes.h:131
os_support.h
AVFormatCommandID
AVFormatCommandID
Command IDs that can be sent to the demuxer.
Definition: avformat.h:2376
ff_network_init
int ff_network_init(void)
Definition: network.c:55
ff_sdp_parse
int ff_sdp_parse(AVFormatContext *s, const char *content)
Parse an SDP description of streams by populating an RTSPState struct within the AVFormatContext; als...
av_get_random_seed
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
Definition: random_seed.c:196
ff_rtp_send_punch_packets
void ff_rtp_send_punch_packets(URLContext *rtp_handle)
Send a dummy packet on both port pairs to set up the connection state in potential NAT routers,...
Definition: rtpdec.c:416
TEARDOWN
@ TEARDOWN
Definition: rtspcodes.h:136
check_sessionid
static int check_sessionid(AVFormatContext *s, RTSPMessageHeader *request)
Definition: rtspdec.c:129
FFInputFormatCommandOption
FFInputFormatCommandOption
Command handling options Different options influencing the behaviour of the FFInputFormat::handle_com...
Definition: demux.h:61
ff_rtsp_send_cmd_with_content_async_stored
int ff_rtsp_send_cmd_with_content_async_stored(AVFormatContext *s, const char *method, const char *url, const char *headers, const unsigned char *send_content, int send_content_length)
Send a command to the RTSP server, storing the reply on future reads.
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
rtsp_submit_command
static int rtsp_submit_command(struct AVFormatContext *s, enum AVFormatCommandID id, void *data)
Definition: rtspdec.c:643
AVRTSPResponse::body_len
size_t body_len
Body payload size.
Definition: avformat.h:2422
RTSP_STATUS_BANDWIDTH
@ RTSP_STATUS_BANDWIDTH
Definition: rtspcodes.h:59
fail
#define fail()
Definition: checkasm.h:218
ff_rtp_get_local_rtp_port
int ff_rtp_get_local_rtp_port(URLContext *h)
Return the local rtp port used by the RTP connection.
Definition: rtpproto.c:514
AVRTSPResponse::reason
char * reason
Reason phrase from the server, describing the status in a human-readable way.
Definition: avformat.h:2417
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:151
RTSPState::nb_rtsp_streams
int nb_rtsp_streams
number of items in the 'rtsp_streams' variable
Definition: rtsp.h:231
read_line
static int read_line(AVFormatContext *s, char *rbuf, const int rbufsize, int *rbuflen)
Definition: rtspdec.c:77
rtsp_read_header
static int rtsp_read_header(AVFormatContext *s)
Definition: rtspdec.c:845
rtsp_read_packet
static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: rtspdec.c:950
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
AVERROR_OPTION_NOT_FOUND
#define AVERROR_OPTION_NOT_FOUND
Option not found.
Definition: error.h:63
ff_rtsp_setup_input_streams
int ff_rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply)
Get the description of the stream and set up the RTSPStream child objects.
Definition: rtspdec.c:715
RTSPStatusMessage::message
const char * message
Definition: rtspdec.c:46
RTSPMessageHeader::content_length
int content_length
length of the data following this header
Definition: rtsp.h:131
RTSP_TRANSPORT_RDT
@ RTSP_TRANSPORT_RDT
Realmedia Data Transport.
Definition: rtsp.h:61
ff_rtsp_tcp_read_packet
int ff_rtsp_tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, uint8_t *buf, int buf_size)
Receive one RTP packet from an TCP interleaved RTSP stream.
Definition: rtspdec.c:886
RTSP_STATE_STREAMING
@ RTSP_STATE_STREAMING
initialized and sending/receiving data
Definition: rtsp.h:204
rtsp.h
RTSPState::lower_transport_mask
int lower_transport_mask
A mask with all requested transport methods.
Definition: rtsp.h:374
rtsp_handle_command
static int rtsp_handle_command(struct AVFormatContext *s, enum FFInputFormatCommandOption opt, enum AVFormatCommandID id, void *data)
Definition: rtspdec.c:701
RTSPMethod
RTSPMethod
Definition: rtspcodes.h:129
RTSPStream::stream_index
int stream_index
corresponding stream index, if any.
Definition: rtsp.h:482
ff_rdt_parse_close
void ff_rdt_parse_close(RDTDemuxContext *s)
Definition: rdt.c:80
first
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
Definition: rate_distortion.txt:12
avassert.h
RTSPState::rtsp_hd_out
URLContext * rtsp_hd_out
Additional output handle, used when input and output are done separately, eg for HTTP tunneling.
Definition: rtsp.h:358
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:236
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
RTSP_FLAG_LISTEN
#define RTSP_FLAG_LISTEN
Wait for incoming connections.
Definition: rtsp.h:460
ff_rtsp_parse_streaming_commands
int ff_rtsp_parse_streaming_commands(AVFormatContext *s)
Parse RTSP commands (OPTIONS, PAUSE and TEARDOWN) during streaming in listen mode.
Definition: rtspdec.c:486
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
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:363
RTSP_STATUS_STATE
@ RTSP_STATUS_STATE
Definition: rtspcodes.h:61
FFInputFormatStreamState
FFInputFormatStreamState
Input format stream state The stream states to be used for FFInputFormat::read_set_state.
Definition: demux.h:51
RTSP_STATUS_TRANSPORT
@ RTSP_STATUS_TRANSPORT
Definition: rtspcodes.h:67
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
RTSPState::nb_byes
int nb_byes
Definition: rtsp.h:366
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:549
RTSPState::control_uri
char control_uri[MAX_URL_SIZE]
some MS RTSP streams contain a URL in the SDP that we need to use for all subsequent RTSP requests,...
Definition: rtsp.h:347
RTSPMessageHeader::transports
RTSPTransportField transports[RTSP_MAX_TRANSPORTS]
describes the complete "Transport:" line of the server in response to a SETUP RTSP command by the cli...
Definition: rtsp.h:144
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
RTSP_STATUS_VERSION
@ RTSP_STATUS_VERSION
Definition: rtspcodes.h:74
ff_rtsp_undo_setup
void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets)
Undo the effect of ff_rtsp_make_setup_request, close the transport_priv and rtp_handle fields.
Definition: rtsp.c:799
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
RTSPState::buffer_size
int buffer_size
Definition: rtsp.h:441
ff_rtsp_open_transport_ctx
int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
Open RTSP transport context.
Definition: rtsp.c:868
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ff_rtsp_fetch_packet
int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
Receive one packet from the RTSPStreams set up in the AVFormatContext (which should contain a RTSPSta...
RTSP_STATUS_INTERNAL
@ RTSP_STATUS_INTERNAL
Definition: rtspcodes.h:69
RTSPMessageHeader::seq
int seq
sequence number
Definition: rtsp.h:146
parse_command_line
static int parse_command_line(AVFormatContext *s, const char *line, int linelen, char *uri, int urisize, char *method, int methodsize, enum RTSPMethod *methodcode)
Definition: rtspdec.c:383
rtsp_read_set_state
static int rtsp_read_set_state(AVFormatContext *s, enum FFInputFormatStreamState state)
Definition: rtspdec.c:615
AVRTSPResponse::body
unsigned char * body
Body payload.
Definition: avformat.h:2427
if
if(ret)
Definition: filter_design.txt:179
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:232
AVFormatContext
Format I/O context.
Definition: avformat.h:1264
internal.h
opts
static AVDictionary * opts
Definition: movenc.c:51
RTSPState::session_id
char session_id[512]
copy of RTSPMessageHeader->session_id, i.e.
Definition: rtsp.h:253
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
RTSPMessageHeader::reason
char reason[256]
The "reason" is meant to specify better the meaning of the error code returned.
Definition: rtsp.h:184
RTSP_STATUS_OK
@ RTSP_STATUS_OK
Definition: rtspcodes.h:33
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
ff_rdt_parse_header
int ff_rdt_parse_header(const uint8_t *buf, int len, int *pset_id, int *pseq_no, int *pstream_id, int *pis_keyframe, uint32_t *ptimestamp)
Actual data handling.
Definition: rdt.c:192
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:783
NULL
#define NULL
Definition: coverity.c:32
RTSPState::rtsp_hd
URLContext * rtsp_hd
Definition: rtsp.h:228
AVRTSPCommandRequest::headers
AVDictionary * headers
Headers sent in the request to the server.
Definition: avformat.h:2394
state
static struct @553 state
av_unreachable
#define av_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
Definition: avassert.h:116
RECORD
@ RECORD
Definition: rtspcodes.h:140
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
rtsp_probe
static int rtsp_probe(const AVProbeData *p)
Definition: rtspdec.c:833
FF_INFMT_COMMAND_GET_REPLY
@ FF_INFMT_COMMAND_GET_REPLY
Definition: demux.h:63
RTSPState::real_setup
enum AVDiscard * real_setup
current stream setup.
Definition: rtsp.h:326
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
RTSP_STATUS_SESSION
@ RTSP_STATUS_SESSION
Definition: rtspcodes.h:60
FF_INFMT_STATE_PLAY
@ FF_INFMT_STATE_PLAY
Definition: demux.h:52
AVRTSPCommandRequest
Definition: avformat.h:2390
rtsp_read_play
static int rtsp_read_play(AVFormatContext *s)
Definition: rtspdec.c:527
AVRTSPResponse
Definition: avformat.h:2407
RTPDemuxContext::rtcp_ts_offset
int64_t rtcp_ts_offset
Definition: rtpdec.h:178
time.h
RTSPState::state
enum RTSPClientState state
indicator of whether we are currently receiving data from the server.
Definition: rtsp.h:239
rtsp_read_record
static int rtsp_read_record(AVFormatContext *s)
Definition: rtspdec.c:361
index
int index
Definition: gxfenc.c:90
ff_rtp_parse_close
void ff_rtp_parse_close(RTPDemuxContext *s)
Definition: rtpdec.c:939
rtsp_read_command_reply
static int rtsp_read_command_reply(AVFormatContext *s, enum AVFormatCommandID id, void **data_out)
Definition: rtspdec.c:670
rtsp_listen
static int rtsp_listen(AVFormatContext *s)
Definition: rtspdec.c:752
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
RTSPState::rtsp_flags
int rtsp_flags
Various option flags for the RTSP muxer/demuxer.
Definition: rtsp.h:408
ff_rtsp_options
const AVOption ff_rtsp_options[]
Definition: rtsp.c:87
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
ff_rtsp_close_connections
void ff_rtsp_close_connections(AVFormatContext *s)
Close all connection handles within the RTSP (de)muxer.
RTSPState
Private data for the RTSP demuxer.
Definition: rtsp.h:226
RTSPState::lower_transport
enum RTSPLowerTransport lower_transport
the negotiated network layer transport protocol; e.g.
Definition: rtsp.h:270
RTSPMessageHeader::range_start
int64_t range_start
Time range of the streams that the server will stream.
Definition: rtsp.h:140
RTPDemuxContext::first_rtcp_ntp_time
uint64_t first_rtcp_ntp_time
Definition: rtpdec.h:177
RTSPState::rtsp_streams
struct RTSPStream ** rtsp_streams
streams in this session
Definition: rtsp.h:233
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
RTSPState::seq
int seq
RTSP command sequence number.
Definition: rtsp.h:249
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:468
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:70
header
static const uint8_t header[24]
Definition: sdr2.c:68
RTSPState::auth_state
HTTPAuthState auth_state
authentication state
Definition: rtsp.h:284
RTPDemuxContext::unwrapped_timestamp
int64_t unwrapped_timestamp
Definition: rtpdec.h:156
line
Definition: graph2dot.c:48
ff_rtsp_parse_line
void ff_rtsp_parse_line(AVFormatContext *s, RTSPMessageHeader *reply, const char *buf, RTSPState *rt, const char *method)
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:233
read_header
static int read_header(FFV1Context *f, RangeCoder *c)
Definition: ffv1dec.c:498
av_strstart
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:36
RTSPState::last_subscription
char last_subscription[1024]
the last value of the "SET_PARAMETER Subscribe:" RTSP command.
Definition: rtsp.h:331
RTSPState::timeout
int timeout
copy of RTSPMessageHeader->timeout, i.e.
Definition: rtsp.h:258
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
RTSPTransportField::client_port_max
int client_port_max
Definition: rtsp.h:103
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
code
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
Definition: filter_design.txt:178
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
RTSPState::need_subscription
int need_subscription
The following are used for Real stream selection.
Definition: rtsp.h:318
rtsp_read_seek
static int rtsp_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: rtspdec.c:1065
rtpproto.h
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:361
url.h
RTSP_LOWER_TRANSPORT_TCP
@ RTSP_LOWER_TRANSPORT_TCP
TCP; interleaved in RTSP.
Definition: rtsp.h:41
demux.h
status_messages
static const struct RTSPStatusMessage status_messages[]
len
int len
Definition: vorbis_enc_data.h:426
RTSP_STATUS_AGGREGATE
@ RTSP_STATUS_AGGREGATE
Definition: rtspcodes.h:65
RTPDemuxContext
Definition: rtpdec.h:148
RTPDemuxContext::timestamp
uint32_t timestamp
Definition: rtpdec.h:154
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
RTSPTransportField::client_port_min
int client_port_min
UDP client ports; these should be the local ports of the UDP RTP (and RTCP) sockets over which we rec...
Definition: rtsp.h:103
rtsp_demuxer_class
static const AVClass rtsp_demuxer_class
Definition: rtspdec.c:1092
version.h
RTSPState::rtp_port_max
int rtp_port_max
Definition: rtsp.h:418
rtsp_read_announce
static int rtsp_read_announce(AVFormatContext *s)
Definition: rtspdec.c:177
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:589
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:744
AVRTSPResponse::status_code
int status_code
Response status code from server.
Definition: avformat.h:2411
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
RTPDemuxContext::last_sr
AVRTCPSenderReport last_sr
Last RTCP SR data.
Definition: rtpdec.h:179
av_malloc
void * av_malloc(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:98
avformat.h
RTSPStatusMessage
Definition: rtspdec.c:44
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:122
network.h
id
enum AVCodecID id
Definition: dts2pts.c:549
HTTPAuthState::stale
int stale
Auth ok, but needs to be resent with a new nonce.
Definition: httpauth.h:71
tls.h
RTSP_DEFAULT_PORT
#define RTSP_DEFAULT_PORT
Definition: rtsp.h:75
RTSPState::transport
enum RTSPTransport transport
the negotiated data/packet transport protocol; e.g.
Definition: rtsp.h:266
random_seed.h
MAX_URL_SIZE
#define MAX_URL_SIZE
Definition: internal.h:30
RTPDemuxContext::base_timestamp
uint32_t base_timestamp
Definition: rtpdec.h:155
RTSPStream::control_url
char control_url[MAX_URL_SIZE]
url for this stream (from SDP)
Definition: rtsp.h:488
AVERROR_STREAM_NOT_FOUND
#define AVERROR_STREAM_NOT_FOUND
Stream not found.
Definition: error.h:67
SETUP
@ SETUP
Definition: rtspcodes.h:133
RTSPStream::interleaved_max
int interleaved_max
Definition: rtsp.h:486
RTSPStatusCode
RTSPStatusCode
RTSP handling.
Definition: rtspcodes.h:31
RTSP_SERVER_WMS
@ RTSP_SERVER_WMS
Windows Media server.
Definition: rtsp.h:216
PAUSE
@ PAUSE
Definition: rtspcodes.h:135
RTSP_STATUS_SERVICE
@ RTSP_STATUS_SERVICE
Definition: rtspcodes.h:72
ff_rtsp_demuxer
const FFInputFormat ff_rtsp_demuxer
Definition: rtspdec.c:1099
RTSPMessageHeader
This describes the server response to each RTSP command.
Definition: rtsp.h:129
dict_to_headers
static char * dict_to_headers(AVDictionary *headers)
Definition: rtspdec.c:628
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
AVFORMAT_COMMAND_RTSP_SET_PARAMETER
@ AVFORMAT_COMMAND_RTSP_SET_PARAMETER
Send a RTSP SET_PARAMETER request to the server.
Definition: avformat.h:2387
FF_INFMT_COMMAND_SUBMIT
@ FF_INFMT_COMMAND_SUBMIT
Definition: demux.h:62
av_dict_set_int
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition: dict.c:177
RTSPState::real_setup_cache
enum AVDiscard * real_setup_cache
stream setup during the last frame read.
Definition: rtsp.h:322
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:272
RTSP_STATE_IDLE
@ RTSP_STATE_IDLE
not initialized
Definition: rtsp.h:203
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
mem.h
RTSP_STATUS_ONLY_AGGREGATE
@ RTSP_STATUS_ONLY_AGGREGATE
Definition: rtspcodes.h:66
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:558
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:90
rdt.h
headers
FFmpeg currently uses a custom build this text attempts to document some of its obscure features and options Makefile the full command issued by make and its output will be shown on the screen DBG Preprocess x86 external assembler files to a dbg asm file in the object which then gets compiled Helps in developing those assembler files DESTDIR Destination directory for the install useful to prepare packages or install FFmpeg in cross environments GEN Set to ‘1’ to generate the missing or mismatched references Makefile builds all the libraries and the executables fate Run the fate test note that you must have installed it fate list List all fate regression test targets fate list failing List the fate tests that failed the last time they were executed fate clear reports Remove the test reports from previous test libraries and programs examples Build all examples located in doc examples checkheaders Check headers dependencies alltools Build all tools in tools directory config Reconfigure the project with the current configuration tools target_dec_< decoder > _fuzzer Build fuzzer to fuzz the specified decoder tools target_bsf_< filter > _fuzzer Build fuzzer to fuzz the specified bitstream filter Useful standard make this is useful to reduce unneeded rebuilding when changing headers
Definition: build_system.txt:64
AVPacket
This structure stores compressed data.
Definition: packet.h:565
RTSPState::server_type
enum RTSPServerType server_type
brand of server that we're talking to; e.g.
Definition: rtsp.h:275
RTSPMessageHeader::content_type
char content_type[64]
Content type header.
Definition: rtsp.h:189
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
FFInputFormat
Definition: demux.h:66
ff_rtp_reset_packet_queue
void ff_rtp_reset_packet_queue(RTPDemuxContext *s)
Definition: rtpdec.c:762
RTSPState::packets
uint64_t packets
The number of returned packets.
Definition: rtsp.h:379
RTSPTransportField::mode_record
int mode_record
transport set to record data
Definition: rtsp.h:114
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
av_strlcpy
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:85
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
RTSPMessageHeader::session_id
char session_id[512]
the "Session:" field.
Definition: rtsp.h:150
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_rtsp_make_setup_request
int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, int lower_transport, const char *real_challenge)
Do the SETUP requests for each stream for the chosen lower transport mode.
RTSPStatusMessage::code
enum RTSPStatusCode code
Definition: rtspdec.c:45
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
avstring.h
AVDiscard
AVDiscard
Definition: defs.h:223
ff_rtsp_connect
int ff_rtsp_connect(AVFormatContext *s)
Connect to the RTSP server and set up the individual media streams.
AVERROR_PROTOCOL_NOT_FOUND
#define AVERROR_PROTOCOL_NOT_FOUND
Protocol not found.
Definition: error.h:65
snprintf
#define snprintf
Definition: snprintf.h:34
RTSPState::pending_packet
int pending_packet
Indicates if a packet is pending to be read (useful for interleaved reads)
Definition: rtsp.h:309
rtsp_read_pause
static int rtsp_read_pause(AVFormatContext *s)
Definition: rtspdec.c:598
av_dict_iterate
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition: dict.c:42
RTSPS_DEFAULT_PORT
#define RTSPS_DEFAULT_PORT
Definition: rtsp.h:76
RTSP_LOWER_TRANSPORT_UDP
@ RTSP_LOWER_TRANSPORT_UDP
UDP/unicast.
Definition: rtsp.h:40
line
The official guide to swscale for confused that consecutive non overlapping rectangles of slice_bottom special converter These generally are unscaled converters of common like for each output line the vertical scaler pulls lines from a ring buffer When the ring buffer does not contain the wanted line
Definition: swscale.txt:40
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98