summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-05-23 21:41:13 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-05-23 21:48:31 +0200
commitd0ad91c258821708ce21b4ae53018922ef1f5614 (patch)
tree95332c7c22137cedd30a84bcc51cf6924ee2d631 /libavformat
parentd0f78e77e1cde44532d613525a4f521e8effe3ed (diff)
parent3f9d6e423978f5e905def374e9c2e9166e3ebb2c (diff)
Merge remote-tracking branch 'qatar/master'
* qatar/master: os_support: Define SHUT_RD, SHUT_WR and SHUT_RDWR on OS/2 http: Add support for reading http POST reply headers http: Add http_shutdown() for ending writing of posts tcp: Allow signalling end of reading/writing avio: Add a function for signalling end of reading/writing lavfi: fix comment, audio is supported now. lavfi: fix incorrect comment. lavfi: remove avfilter_null_* from public API on next bump. lavfi: remove avfilter_default_* from public API on next bump. lavfi: deprecate default config_props() callback and refactor avfilter_config_links() avfiltergraph: smarter sample format selection. avconv: rename transcode_audio/video to decode_audio/video. asyncts: reset delta to 0 when it's not used. x86: lavc: use %if HAVE_AVX guards around AVX functions in yasm code. dwt: return errors from ff_slice_buffer_init() Conflicts: ffmpeg.c libavfilter/avfilter.c libavfilter/avfilter.h libavfilter/formats.c libavfilter/version.h libavfilter/vf_blackframe.c libavfilter/vf_drawtext.c libavfilter/vf_fade.c libavfilter/vf_format.c libavfilter/vf_showinfo.c libavfilter/video.c libavfilter/video.h Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/avio.c7
-rw-r--r--libavformat/http.c37
-rw-r--r--libavformat/os_support.h12
-rw-r--r--libavformat/tcp.c17
-rw-r--r--libavformat/url.h13
5 files changed, 83 insertions, 3 deletions
diff --git a/libavformat/avio.c b/libavformat/avio.c
index e732d1ad4a..c7b7bc67d5 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -376,6 +376,13 @@ int ffurl_get_file_handle(URLContext *h)
return h->prot->url_get_file_handle(h);
}
+int ffurl_shutdown(URLContext *h, int flags)
+{
+ if (!h->prot->url_shutdown)
+ return AVERROR(EINVAL);
+ return h->prot->url_shutdown(h, flags);
+}
+
int ff_check_interrupt(AVIOInterruptCB *cb)
{
int ret;
diff --git a/libavformat/http.c b/libavformat/http.c
index 7a45fa233c..40c06d6083 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -52,6 +52,8 @@ typedef struct {
char *headers;
int willclose; /**< Set if the server correctly handles Connection: close and will close the connection after feeding us the content. */
int chunked_post;
+ int end_chunked_post; /**< A flag which indicates if the end of chunked encoding has been sent. */
+ int end_header; /**< A flag which indicates we have finished to read POST reply. */
} HTTPContext;
#define OFFSET(x) offsetof(HTTPContext, x)
@@ -251,8 +253,10 @@ static int process_line(URLContext *h, char *line, int line_count,
char *tag, *p, *end;
/* end of header */
- if (line[0] == '\0')
+ if (line[0] == '\0') {
+ s->end_header = 1;
return 0;
+ }
p = line;
if (line_count == 0) {
@@ -419,6 +423,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
s->off = 0;
s->filesize = -1;
s->willclose = 0;
+ s->end_chunked_post = 0;
if (post) {
/* Pretend that it did work. We didn't read any header yet, since
* we've still to send the POST data, but the code calling this
@@ -464,6 +469,17 @@ static int http_buf_read(URLContext *h, uint8_t *buf, int size)
static int http_read(URLContext *h, uint8_t *buf, int size)
{
HTTPContext *s = h->priv_data;
+ int err, new_location;
+
+ if (s->end_chunked_post) {
+ if (!s->end_header) {
+ err = http_read_header(h, &new_location);
+ if (err < 0)
+ return err;
+ }
+
+ return http_buf_read(h, buf, size);
+ }
if (s->chunksize >= 0) {
if (!s->chunksize) {
@@ -516,16 +532,30 @@ static int http_write(URLContext *h, const uint8_t *buf, int size)
return size;
}
-static int http_close(URLContext *h)
+static int http_shutdown(URLContext *h, int flags)
{
int ret = 0;
char footer[] = "0\r\n\r\n";
HTTPContext *s = h->priv_data;
/* signal end of chunked encoding if used */
- if ((h->flags & AVIO_FLAG_WRITE) && s->chunked_post) {
+ if ((flags & AVIO_FLAG_WRITE) && s->chunked_post) {
ret = ffurl_write(s->hd, footer, sizeof(footer) - 1);
ret = ret > 0 ? 0 : ret;
+ s->end_chunked_post = 1;
+ }
+
+ return ret;
+}
+
+static int http_close(URLContext *h)
+{
+ int ret = 0;
+ HTTPContext *s = h->priv_data;
+
+ if (!s->end_chunked_post) {
+ /* Close the write direction by sending the end of chunked encoding. */
+ ret = http_shutdown(h, h->flags);
}
if (s->hd)
@@ -585,6 +615,7 @@ URLProtocol ff_http_protocol = {
.url_seek = http_seek,
.url_close = http_close,
.url_get_file_handle = http_get_file_handle,
+ .url_shutdown = http_shutdown,
.priv_data_size = sizeof(HTTPContext),
.priv_data_class = &http_context_class,
.flags = URL_PROTOCOL_FLAG_NETWORK,
diff --git a/libavformat/os_support.h b/libavformat/os_support.h
index 159d4d7f85..bf2698405b 100644
--- a/libavformat/os_support.h
+++ b/libavformat/os_support.h
@@ -48,6 +48,18 @@ static inline int is_dos_path(const char *path)
return 0;
}
+#if defined(__OS2__)
+#define SHUT_RD 0
+#define SHUT_WR 1
+#define SHUT_RDWR 2
+#endif
+
+#if defined(_WIN32)
+#define SHUT_RD SD_RECEIVE
+#define SHUT_WR SD_SEND
+#define SHUT_RDWR SD_BOTH
+#endif
+
#if defined(_WIN32) && !defined(__MINGW32CE__)
int ff_win32_open(const char *filename, int oflag, int pmode);
#define open ff_win32_open
diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index fa88467164..db8dba2630 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -182,6 +182,22 @@ static int tcp_write(URLContext *h, const uint8_t *buf, int size)
return ret < 0 ? ff_neterrno() : ret;
}
+static int tcp_shutdown(URLContext *h, int flags)
+{
+ TCPContext *s = h->priv_data;
+ int how;
+
+ if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ) {
+ how = SHUT_RDWR;
+ } else if (flags & AVIO_FLAG_WRITE) {
+ how = SHUT_WR;
+ } else {
+ how = SHUT_RD;
+ }
+
+ return shutdown(s->fd, how);
+}
+
static int tcp_close(URLContext *h)
{
TCPContext *s = h->priv_data;
@@ -202,6 +218,7 @@ URLProtocol ff_tcp_protocol = {
.url_write = tcp_write,
.url_close = tcp_close,
.url_get_file_handle = tcp_get_file_handle,
+ .url_shutdown = tcp_shutdown,
.priv_data_size = sizeof(TCPContext),
.flags = URL_PROTOCOL_FLAG_NETWORK,
};
diff --git a/libavformat/url.h b/libavformat/url.h
index dc483a3ea9..6ad754e19f 100644
--- a/libavformat/url.h
+++ b/libavformat/url.h
@@ -81,6 +81,7 @@ typedef struct URLProtocol {
int64_t (*url_read_seek)(URLContext *h, int stream_index,
int64_t timestamp, int flags);
int (*url_get_file_handle)(URLContext *h);
+ int (*url_shutdown)(URLContext *h, int flags);
int priv_data_size;
const AVClass *priv_data_class;
int flags;
@@ -201,6 +202,18 @@ int64_t ffurl_size(URLContext *h);
int ffurl_get_file_handle(URLContext *h);
/**
+ * Signal the URLContext that we are done reading or writing the stream.
+ *
+ * @param h pointer to the resource
+ * @param flags flags which control how the resource indicated by url
+ * is to be shutdown
+ *
+ * @return a negative value if an error condition occurred, 0
+ * otherwise
+ */
+int ffurl_shutdown(URLContext *h, int flags);
+
+/**
* Register the URLProtocol protocol.
*
* @param size the size of the URLProtocol struct referenced