static void rtsp_cmd_options(HTTPContext *c, const char *url);
static void rtsp_cmd_setup(HTTPContext *c, const char *url, RTSPMessageHeader *h);
static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h);
-static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h);
-static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h);
+static void rtsp_cmd_interrupt(HTTPContext *c, const char *url, RTSPMessageHeader *h, int pause_only);
/* SDP handling */
static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
if (len < 0) {
if (ff_neterrno() != AVERROR(EAGAIN) &&
ff_neterrno() != AVERROR(EINTR)) {
- /* error : close connection */
- av_freep(&c->pb_buffer);
- return -1;
+ goto close_connection;
}
} else {
c->buffer_ptr += len;
break;
case RTSPSTATE_SEND_REPLY:
- if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
- av_freep(&c->pb_buffer);
- return -1;
- }
+ if (c->poll_entry->revents & (POLLERR | POLLHUP))
+ goto close_connection;
/* no need to write if no events */
if (!(c->poll_entry->revents & POLLOUT))
return 0;
if (len < 0) {
if (ff_neterrno() != AVERROR(EAGAIN) &&
ff_neterrno() != AVERROR(EINTR)) {
- /* error : close connection */
- av_freep(&c->pb_buffer);
- return -1;
+ goto close_connection;
}
} else {
c->buffer_ptr += len;
return -1;
}
return 0;
+
+close_connection:
+ av_freep(&c->pb_buffer);
+ return -1;
}
static int extract_rates(char *rates, int ratelen, const char *request)
}
avio_printf(pb, "HTTP/1.0 200 OK\r\n");
- avio_printf(pb, "Content-type: %s\r\n", "text/html");
+ avio_printf(pb, "Content-type: text/html\r\n");
avio_printf(pb, "Pragma: no-cache\r\n");
avio_printf(pb, "\r\n");
return ret;
}
- /* choose stream as clock source (we favorize video stream if
- present) for packet sending */
+ /* choose stream as clock source (we favor the video stream if
+ * present) for packet sending */
c->pts_stream_index = 0;
for(i=0;i<c->stream->nb_streams;i++) {
if (c->pts_stream_index == 0 &&
*(c->fmt_ctx.streams[i]) = *src;
c->fmt_ctx.streams[i]->priv_data = 0;
- c->fmt_ctx.streams[i]->codec->frame_number = 0; /* XXX: should be done in
- AVStream, not in codec */
+ /* XXX: should be done in AVStream, not in codec */
+ c->fmt_ctx.streams[i]->codec->frame_number = 0;
}
/* set output format parameters */
c->fmt_ctx.oformat = c->stream->fmt;
/*
* HACK to avoid mpeg ps muxer to spit many underflow errors
* Default value from FFmpeg
- * Try to set it use configuration option
+ * Try to set it using configuration option
*/
c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE);
goto redo;
} else {
no_loop:
- /* must send trailer now because eof or error */
+ /* must send trailer now because EOF or error */
c->state = HTTPSTATE_SEND_DATA_TRAILER;
}
}
send_it:
ist = c->fmt_in->streams[source_index];
/* specific handling for RTP: we use several
- output stream (one for each RTP
- connection). XXX: need more abstract handling */
+ * output streams (one for each RTP connection).
+ * XXX: need more abstract handling */
if (c->is_packetized) {
/* compute send time and duration */
c->cur_pts = av_rescale_q(pkt.dts, ist->time_base, AV_TIME_BASE_Q);
/* should convert the format at the same time */
/* send data starting at c->buffer_ptr to the output connection
- (either UDP or TCP connection) */
+ * (either UDP or TCP) */
static int http_send_data(HTTPContext *c)
{
int len, ret;
else if (!strcmp(cmd, "PLAY"))
rtsp_cmd_play(c, url, header);
else if (!strcmp(cmd, "PAUSE"))
- rtsp_cmd_pause(c, url, header);
+ rtsp_cmd_interrupt(c, url, header, 1);
else if (!strcmp(cmd, "TEARDOWN"))
- rtsp_cmd_teardown(c, url, header);
+ rtsp_cmd_interrupt(c, url, header, 0);
else
rtsp_reply_error(c, RTSP_STATUS_METHOD);
avio_printf(c->pb, "\r\n");
}
-static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h)
+static void rtsp_cmd_interrupt(HTTPContext *c, const char *url, RTSPMessageHeader *h, int pause_only)
{
HTTPContext *rtp_c;
return;
}
- if (rtp_c->state != HTTPSTATE_SEND_DATA &&
- rtp_c->state != HTTPSTATE_WAIT_FEED) {
- rtsp_reply_error(c, RTSP_STATUS_STATE);
- return;
- }
-
- rtp_c->state = HTTPSTATE_READY;
- rtp_c->first_pts = AV_NOPTS_VALUE;
- /* now everything is OK, so we can send the connection parameters */
- rtsp_reply_header(c, RTSP_STATUS_OK);
- /* session ID */
- avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
- avio_printf(c->pb, "\r\n");
-}
-
-static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h)
-{
- HTTPContext *rtp_c;
-
- rtp_c = find_rtp_session_with_url(url, h->session_id);
- if (!rtp_c) {
- rtsp_reply_error(c, RTSP_STATUS_SESSION);
- return;
+ if (pause_only) {
+ if (rtp_c->state != HTTPSTATE_SEND_DATA &&
+ rtp_c->state != HTTPSTATE_WAIT_FEED) {
+ rtsp_reply_error(c, RTSP_STATUS_STATE);
+ return;
+ }
+ rtp_c->state = HTTPSTATE_READY;
+ rtp_c->first_pts = AV_NOPTS_VALUE;
}
/* now everything is OK, so we can send the connection parameters */
avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
avio_printf(c->pb, "\r\n");
- /* abort the session */
- close_connection(rtp_c);
+ if (!pause_only)
+ close_connection(rtp_c);
}
-
/********************************************************************/
/* RTP handling */
}
} else {
/* live streams must use the actual feed's codec since it may be
- * updated later to carry extradata needed by the streams.
+ * updated later to carry extradata needed by them.
*/
fst->codec = codec;
}
return ret;
}
-static AVOutputFormat *ffserver_guess_format(const char *short_name, const char *filename,
- const char *mime_type)
+static AVOutputFormat *ffserver_guess_format(const char *short_name, const char *filename, const char *mime_type)
{
AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type);