Revision b7dc88fc
libavformat/rtsp.c | ||
---|---|---|
584 | 584 |
if (s->oformat) { |
585 | 585 |
AVFormatContext *rtpctx = rtsp_st->transport_priv; |
586 | 586 |
av_write_trailer(rtpctx); |
587 |
if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) { |
|
588 |
uint8_t *ptr; |
|
589 |
url_close_dyn_buf(rtpctx->pb, &ptr); |
|
590 |
av_free(ptr); |
|
591 |
} else { |
|
587 | 592 |
url_fclose(rtpctx->pb); |
593 |
} |
|
588 | 594 |
av_metadata_free(&rtpctx->streams[0]->metadata); |
589 | 595 |
av_metadata_free(&rtpctx->metadata); |
590 | 596 |
av_free(rtpctx->streams[0]); |
... | ... | |
644 | 650 |
av_free(rtpctx->streams[0]->codec); |
645 | 651 |
rtpctx->streams[0]->codec = st->codec; |
646 | 652 |
|
653 |
if (handle) { |
|
647 | 654 |
url_fdopen(&rtpctx->pb, handle); |
655 |
} else |
|
656 |
url_open_dyn_packet_buf(&rtpctx->pb, RTSP_TCP_MAX_PACKET_SIZE); |
|
648 | 657 |
ret = av_write_header(rtpctx); |
649 | 658 |
|
650 | 659 |
if (ret) { |
660 |
if (handle) { |
|
651 | 661 |
url_fclose(rtpctx->pb); |
662 |
} else { |
|
663 |
uint8_t *ptr; |
|
664 |
url_close_dyn_buf(rtpctx->pb, &ptr); |
|
665 |
av_free(ptr); |
|
666 |
} |
|
652 | 667 |
av_free(rtpctx->streams[0]); |
653 | 668 |
av_free(rtpctx); |
654 | 669 |
return NULL; |
... | ... | |
1464 | 1479 |
lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1; |
1465 | 1480 |
|
1466 | 1481 |
if (s->oformat) { |
1467 |
/* Only UDP output is supported at the moment. */ |
|
1468 |
lower_transport_mask &= 1 << RTSP_LOWER_TRANSPORT_UDP; |
|
1482 |
/* Only UDP or TCP - UDP multicast isn't supported. */ |
|
1483 |
lower_transport_mask &= (1 << RTSP_LOWER_TRANSPORT_UDP) | |
|
1484 |
(1 << RTSP_LOWER_TRANSPORT_TCP); |
|
1469 | 1485 |
if (!lower_transport_mask) { |
1470 | 1486 |
av_log(s, AV_LOG_ERROR, "Unsupported lower transport method, " |
1471 |
"only UDP is supported for output.\n");
|
|
1487 |
"only UDP and TCP are supported for output.\n");
|
|
1472 | 1488 |
err = AVERROR(EINVAL); |
1473 | 1489 |
goto fail; |
1474 | 1490 |
} |
libavformat/rtspenc.c | ||
---|---|---|
27 | 27 |
#endif |
28 | 28 |
#include "network.h" |
29 | 29 |
#include "rtsp.h" |
30 |
#include <libavutil/intreadwrite.h> |
|
30 | 31 |
|
31 | 32 |
static int rtsp_write_record(AVFormatContext *s) |
32 | 33 |
{ |
... | ... | |
63 | 64 |
return 0; |
64 | 65 |
} |
65 | 66 |
|
67 |
static int tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st) |
|
68 |
{ |
|
69 |
RTSPState *rt = s->priv_data; |
|
70 |
AVFormatContext *rtpctx = rtsp_st->transport_priv; |
|
71 |
uint8_t *buf, *ptr; |
|
72 |
int size; |
|
73 |
uint8_t interleave_header[4]; |
|
74 |
|
|
75 |
size = url_close_dyn_buf(rtpctx->pb, &buf); |
|
76 |
ptr = buf; |
|
77 |
while (size > 4) { |
|
78 |
uint32_t packet_len = AV_RB32(ptr); |
|
79 |
int id; |
|
80 |
ptr += 4; |
|
81 |
size -= 4; |
|
82 |
if (packet_len > size || packet_len < 2) |
|
83 |
break; |
|
84 |
if (ptr[1] >= 200 && ptr[1] <= 204) |
|
85 |
id = rtsp_st->interleaved_max; /* RTCP */ |
|
86 |
else |
|
87 |
id = rtsp_st->interleaved_min; /* RTP */ |
|
88 |
interleave_header[0] = '$'; |
|
89 |
interleave_header[1] = id; |
|
90 |
AV_WB16(interleave_header + 2, packet_len); |
|
91 |
url_write(rt->rtsp_hd, interleave_header, 4); |
|
92 |
url_write(rt->rtsp_hd, ptr, packet_len); |
|
93 |
ptr += packet_len; |
|
94 |
size -= packet_len; |
|
95 |
} |
|
96 |
av_free(buf); |
|
97 |
url_open_dyn_packet_buf(&rtpctx->pb, RTSP_TCP_MAX_PACKET_SIZE); |
|
98 |
return 0; |
|
99 |
} |
|
100 |
|
|
66 | 101 |
static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt) |
67 | 102 |
{ |
68 | 103 |
RTSPState *rt = s->priv_data; |
... | ... | |
111 | 146 |
* the internal stream_index = 0 becomes visible to the muxer user. */ |
112 | 147 |
local_pkt = *pkt; |
113 | 148 |
local_pkt.stream_index = 0; |
114 |
return av_write_frame(rtpctx, &local_pkt); |
|
149 |
ret = av_write_frame(rtpctx, &local_pkt); |
|
150 |
/* av_write_frame does all the RTP packetization. If using TCP as |
|
151 |
* transport, rtpctx->pb is only a dyn_packet_buf that queues up the |
|
152 |
* packets, so we need to send them out on the TCP connection separately. |
|
153 |
*/ |
|
154 |
if (!ret && rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) |
|
155 |
ret = tcp_write_packet(s, rtsp_st); |
|
156 |
return ret; |
|
115 | 157 |
} |
116 | 158 |
|
117 | 159 |
static int rtsp_write_close(AVFormatContext *s) |
Also available in: Unified diff