|
|
@@ -1349,6 +1349,54 @@ static int rtsp_setup_input_streams(AVFormatContext *s) |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static int rtsp_setup_output_streams(AVFormatContext *s) |
|
|
|
{ |
|
|
|
RTSPState *rt = s->priv_data; |
|
|
|
RTSPMessageHeader reply1, *reply = &reply1; |
|
|
|
char cmd[1024]; |
|
|
|
int i; |
|
|
|
char *sdp; |
|
|
|
|
|
|
|
/* Announce the stream */ |
|
|
|
snprintf(cmd, sizeof(cmd), |
|
|
|
"ANNOUNCE %s RTSP/1.0\r\n" |
|
|
|
"Content-Type: application/sdp\r\n", |
|
|
|
s->filename); |
|
|
|
sdp = av_mallocz(8192); |
|
|
|
if (sdp == NULL) |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
if (avf_sdp_create(&s, 1, sdp, 8192)) { |
|
|
|
av_free(sdp); |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
} |
|
|
|
av_log(s, AV_LOG_INFO, "SDP:\n%s\n", sdp); |
|
|
|
rtsp_send_cmd_with_content(s, cmd, reply, NULL, sdp, strlen(sdp)); |
|
|
|
av_free(sdp); |
|
|
|
if (reply->status_code != RTSP_STATUS_OK) |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
|
|
|
/* Set up the RTSPStreams for each AVStream */ |
|
|
|
for (i = 0; i < s->nb_streams; i++) { |
|
|
|
RTSPStream *rtsp_st; |
|
|
|
AVStream *st = s->streams[i]; |
|
|
|
|
|
|
|
rtsp_st = av_mallocz(sizeof(RTSPStream)); |
|
|
|
if (!rtsp_st) |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st); |
|
|
|
|
|
|
|
st->priv_data = rtsp_st; |
|
|
|
rtsp_st->stream_index = i; |
|
|
|
|
|
|
|
av_strlcpy(rtsp_st->control_url, s->filename, sizeof(rtsp_st->control_url)); |
|
|
|
/* Note, this must match the relative uri set in the sdp content */ |
|
|
|
av_strlcatf(rtsp_st->control_url, sizeof(rtsp_st->control_url), |
|
|
|
"/streamid=%d", i); |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static int rtsp_connect(AVFormatContext *s) |
|
|
|
{ |
|
|
|
RTSPState *rt = s->priv_data; |
|
|
@@ -1406,6 +1454,17 @@ redirect: |
|
|
|
if (!lower_transport_mask) |
|
|
|
lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1; |
|
|
|
|
|
|
|
if (s->oformat) { |
|
|
|
/* Only UDP output is supported at the moment. */ |
|
|
|
lower_transport_mask &= 1 << RTSP_LOWER_TRANSPORT_UDP; |
|
|
|
if (!lower_transport_mask) { |
|
|
|
av_log(s, AV_LOG_ERROR, "Unsupported lower transport method, " |
|
|
|
"only UDP is supported for output.\n"); |
|
|
|
err = AVERROR(EINVAL); |
|
|
|
goto fail; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* open the tcp connexion */ |
|
|
|
snprintf(tcpname, sizeof(tcpname), "tcp://%s:%d", host, port); |
|
|
|
if (url_open(&rtsp_hd, tcpname, URL_RDWR) < 0) { |
|
|
@@ -1455,7 +1514,10 @@ redirect: |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if (s->iformat) |
|
|
|
err = rtsp_setup_input_streams(s); |
|
|
|
else |
|
|
|
err = rtsp_setup_output_streams(s); |
|
|
|
if (err) |
|
|
|
goto fail; |
|
|
|
|
|
|
|