summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-11-11 02:32:38 +0100
committerMichael Niedermayer <michaelni@gmx.at>2011-11-11 02:50:35 +0100
commit6d91045d835635fe889f684bdf77f68e00b15d0b (patch)
treead30db96b3ae0e94efbb8878e0850bd2945bdaf6 /libavformat
parent554caed2d397e137286f2cc71c6bac477b41fa96 (diff)
parent299809defb05eae093cb72da97dfbbb7e17e08fe (diff)
Merge remote-tracking branch 'qatar/master'
* qatar/master: (29 commits) doc: update libavfilter documentation tls: Use the URLContext as logging context aes: Avoid illegal read and don't generate more key than we use. mpc7: Fix memset call in mpc7_decode_frame function atrac1: use correct context for av_log() apedec: consume the whole packet when copying to the decoder buffer. apedec: do not needlessly copy s->samples to nblocks. apedec: check output buffer size after calculating actual output size apedec: remove unneeded entropy decoder normalization. truespeech: use memmove() in truespeech_update_filters() vorbisdec: remove AVCODEC_MAX_AUDIO_FRAME_SIZE check vorbisdec: remove unneeded buf_size==0 check vorbisdec: return proper error codes instead of made-up ones http: Don't add a Range: bytes=0- header for POST sunrast: Check for invalid/corrupted bitstream http: Change the chunksize AVOption into chunked_post http: Add encoding/decoding flags to the AVOptions avconv: remove some codec-specific hacks crypto: add decoding flag to options. tls: use AVIO_FLAG_NONBLOCK instead of deprecated URL_FLAG_NONBLOCK ... Conflicts: doc/libavfilter.texi libavcodec/atrac1.c libavcodec/sunrast.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/avc.c29
-rw-r--r--libavformat/avio.c5
-rw-r--r--libavformat/crypto.c12
-rw-r--r--libavformat/http.c56
-rw-r--r--libavformat/http.h18
-rw-r--r--libavformat/mmsh.c5
-rw-r--r--libavformat/rtsp.c6
-rw-r--r--libavformat/tls.c12
8 files changed, 69 insertions, 74 deletions
diff --git a/libavformat/avc.c b/libavformat/avc.c
index ed2125b527..eff1ddb121 100644
--- a/libavformat/avc.c
+++ b/libavformat/avc.c
@@ -75,8 +75,11 @@ int ff_avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size)
size = 0;
nal_start = ff_avc_find_startcode(p, end);
- while (nal_start < end) {
- while(!*(nal_start++));
+ for (;;) {
+ while (nal_start < end && !*(nal_start++));
+ if (nal_start == end)
+ break;
+
nal_end = ff_avc_find_startcode(nal_start, end);
avio_wb32(pb, nal_end - nal_start);
avio_write(pb, nal_start, nal_end - nal_start);
@@ -117,22 +120,26 @@ int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
end = buf + len;
/* look for sps and pps */
- while (buf < end) {
- unsigned int size;
+ while (end - buf > 4) {
+ uint32_t size;
uint8_t nal_type;
- size = AV_RB32(buf);
- nal_type = buf[4] & 0x1f;
+ size = FFMIN(AV_RB32(buf), end - buf - 4);
+ buf += 4;
+ nal_type = buf[0] & 0x1f;
+
if (nal_type == 7) { /* SPS */
- sps = buf + 4;
+ sps = buf;
sps_size = size;
} else if (nal_type == 8) { /* PPS */
- pps = buf + 4;
+ pps = buf;
pps_size = size;
}
- buf += size + 4;
+
+ buf += size;
}
- assert(sps);
- assert(pps);
+
+ if (!sps || !pps || sps_size < 4 || sps_size > UINT16_MAX || pps_size > UINT16_MAX)
+ return AVERROR_INVALIDDATA;
avio_w8(pb, 1); /* version */
avio_w8(pb, sps[1]); /* profile */
diff --git a/libavformat/avio.c b/libavformat/avio.c
index 47b2d51ebd..4141d0bd7d 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -338,8 +338,11 @@ int ffurl_close(URLContext *h)
#if CONFIG_NETWORK
ff_network_close();
#endif
- if (h->prot->priv_data_size)
+ if (h->prot->priv_data_size) {
+ if (h->prot->priv_data_class)
+ av_opt_free(h->priv_data);
av_free(h->priv_data);
+ }
av_free(h);
return ret;
}
diff --git a/libavformat/crypto.c b/libavformat/crypto.c
index b9d3e0326f..ea417470b6 100644
--- a/libavformat/crypto.c
+++ b/libavformat/crypto.c
@@ -45,9 +45,10 @@ typedef struct {
} CryptoContext;
#define OFFSET(x) offsetof(CryptoContext, x)
+#define D AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
- {"key", "AES decryption key", OFFSET(key), AV_OPT_TYPE_BINARY },
- {"iv", "AES decryption initialization vector", OFFSET(iv), AV_OPT_TYPE_BINARY },
+ {"key", "AES decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, .flags = D },
+ {"iv", "AES decryption initialization vector", OFFSET(iv), AV_OPT_TYPE_BINARY, .flags = D },
{ NULL }
};
@@ -61,7 +62,7 @@ static const AVClass crypto_class = {
static int crypto_open(URLContext *h, const char *uri, int flags)
{
const char *nested_url;
- int ret;
+ int ret = 0;
CryptoContext *c = h->priv_data;
if (!av_strstart(uri, "crypto+", &nested_url) &&
@@ -95,10 +96,7 @@ static int crypto_open(URLContext *h, const char *uri, int flags)
h->is_streamed = 1;
- return 0;
err:
- av_freep(&c->key);
- av_freep(&c->iv);
return ret;
}
@@ -157,8 +155,6 @@ static int crypto_close(URLContext *h)
if (c->hd)
ffurl_close(c->hd);
av_freep(&c->aes);
- av_freep(&c->key);
- av_freep(&c->iv);
return 0;
}
diff --git a/libavformat/http.c b/libavformat/http.c
index 414eb8719f..5f1837d6ad 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -47,36 +47,33 @@ typedef struct {
int64_t off, filesize;
char location[MAX_URL_SIZE];
HTTPAuthState auth_state;
- unsigned char headers[BUFFER_SIZE];
+ 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;
} HTTPContext;
#define OFFSET(x) offsetof(HTTPContext, x)
+#define D AV_OPT_FLAG_DECODING_PARAM
+#define E AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
-{"chunksize", "use chunked transfer-encoding for posts, -1 disables it, 0 enables it", OFFSET(chunksize), AV_OPT_TYPE_INT64, {.dbl = 0}, -1, 0 }, /* Default to 0, for chunked POSTs */
+{"chunked_post", "use chunked transfer-encoding for posts", OFFSET(chunked_post), AV_OPT_TYPE_INT, {.dbl = 1}, 0, 1, E },
+{"headers", "custom HTTP headers, can override built in default headers", OFFSET(headers), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E },
{NULL}
};
-static const AVClass httpcontext_class = {
- .class_name = "HTTP",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
+#define HTTP_CLASS(flavor)\
+static const AVClass flavor ## _context_class = {\
+ .class_name = #flavor,\
+ .item_name = av_default_item_name,\
+ .option = options,\
+ .version = LIBAVUTIL_VERSION_INT,\
};
+HTTP_CLASS(http);
+HTTP_CLASS(https);
+
static int http_connect(URLContext *h, const char *path, const char *hoststr,
const char *auth, int *new_location);
-void ff_http_set_headers(URLContext *h, const char *headers)
-{
- HTTPContext *s = h->priv_data;
- int len = strlen(headers);
-
- if (len && strcmp("\r\n", headers + len - 2))
- av_log(h, AV_LOG_ERROR, "No trailing CRLF found in HTTP header.\n");
-
- av_strlcpy(s->headers, headers, sizeof(s->headers));
-}
-
void ff_http_init_auth_state(URLContext *dest, const URLContext *src)
{
memcpy(&((HTTPContext*)dest->priv_data)->auth_state,
@@ -168,6 +165,12 @@ static int http_open(URLContext *h, const char *uri, int flags)
s->filesize = -1;
av_strlcpy(s->location, uri, sizeof(s->location));
+ if (s->headers) {
+ int len = strlen(s->headers);
+ if (len < 2 || strcmp("\r\n", s->headers + len - 2))
+ av_log(h, AV_LOG_WARNING, "No trailing CRLF found in HTTP header.\n");
+ }
+
return http_open_cnx(h);
}
static int http_getc(HTTPContext *s)
@@ -285,6 +288,8 @@ static int process_line(URLContext *h, char *line, int line_count,
static inline int has_header(const char *str, const char *header)
{
/* header + 2 to skip over CRLF prefix. (make sure you have one!) */
+ if (!str)
+ return 0;
return av_stristart(str, header + 2, NULL) || av_stristr(str, header);
}
@@ -312,7 +317,7 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr,
if (!has_header(s->headers, "\r\nAccept: "))
len += av_strlcpy(headers + len, "Accept: */*\r\n",
sizeof(headers) - len);
- if (!has_header(s->headers, "\r\nRange: "))
+ if (!has_header(s->headers, "\r\nRange: ") && !post)
len += av_strlcatf(headers + len, sizeof(headers) - len,
"Range: bytes=%"PRId64"-\r\n", s->off);
if (!has_header(s->headers, "\r\nConnection: "))
@@ -323,7 +328,8 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr,
"Host: %s\r\n", hoststr);
/* now add in custom headers */
- av_strlcpy(headers+len, s->headers, sizeof(headers)-len);
+ if (s->headers)
+ av_strlcpy(headers + len, s->headers, sizeof(headers) - len);
snprintf(s->buffer, sizeof(s->buffer),
"%s %s HTTP/1.1\r\n"
@@ -333,7 +339,7 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr,
"\r\n",
post ? "POST" : "GET",
path,
- post && s->chunksize >= 0 ? "Transfer-Encoding: chunked\r\n" : "",
+ post && s->chunked_post ? "Transfer-Encoding: chunked\r\n" : "",
headers,
authstr ? authstr : "");
@@ -430,7 +436,7 @@ static int http_write(URLContext *h, const uint8_t *buf, int size)
char crlf[] = "\r\n";
HTTPContext *s = h->priv_data;
- if (s->chunksize == -1) {
+ if (!s->chunked_post) {
/* non-chunked data is sent without any special encoding */
return ffurl_write(s->hd, buf, size);
}
@@ -456,7 +462,7 @@ static int http_close(URLContext *h)
HTTPContext *s = h->priv_data;
/* signal end of chunked encoding if used */
- if ((h->flags & AVIO_FLAG_WRITE) && s->chunksize != -1) {
+ if ((h->flags & AVIO_FLAG_WRITE) && s->chunked_post) {
ret = ffurl_write(s->hd, footer, sizeof(footer) - 1);
ret = ret > 0 ? 0 : ret;
}
@@ -519,7 +525,7 @@ URLProtocol ff_http_protocol = {
.url_close = http_close,
.url_get_file_handle = http_get_file_handle,
.priv_data_size = sizeof(HTTPContext),
- .priv_data_class = &httpcontext_class,
+ .priv_data_class = &http_context_class,
};
#endif
#if CONFIG_HTTPS_PROTOCOL
@@ -532,6 +538,6 @@ URLProtocol ff_https_protocol = {
.url_close = http_close,
.url_get_file_handle = http_get_file_handle,
.priv_data_size = sizeof(HTTPContext),
- .priv_data_class = &httpcontext_class,
+ .priv_data_class = &https_context_class,
};
#endif
diff --git a/libavformat/http.h b/libavformat/http.h
index 19c4099ef0..342434d202 100644
--- a/libavformat/http.h
+++ b/libavformat/http.h
@@ -25,24 +25,6 @@
#include "url.h"
/**
- * Set custom HTTP headers.
- * A trailing CRLF ("\r\n") is required for custom headers.
- * Passing in an empty header string ("\0") will reset to defaults.
- *
- * The following headers can be overriden by custom values,
- * otherwise they will be set to their defaults.
- * -User-Agent
- * -Accept
- * -Range
- * -Host
- * -Connection
- *
- * @param h URL context for this HTTP connection
- * @param headers the custom headers to set
- */
-void ff_http_set_headers(URLContext *h, const char *headers);
-
-/**
* Initialize the authentication state based on another HTTP URLContext.
* This can be used to pre-initialize the authentication parameters if
* they are known beforehand, to avoid having to do an initial failing
diff --git a/libavformat/mmsh.c b/libavformat/mmsh.c
index f54a976e19..c710ad9ccc 100644
--- a/libavformat/mmsh.c
+++ b/libavformat/mmsh.c
@@ -28,6 +28,7 @@
#include <string.h>
#include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
#include "internal.h"
#include "mms.h"
#include "asf.h"
@@ -246,7 +247,7 @@ static int mmsh_open_internal(URLContext *h, const char *uri, int flags, int tim
CLIENTGUID
"Connection: Close\r\n",
host, port, mmsh->request_seq++);
- ff_http_set_headers(mms->mms_hd, headers);
+ av_opt_set(mms->mms_hd->priv_data, "headers", headers, 0);
err = ffurl_connect(mms->mms_hd);
if (err) {
@@ -293,7 +294,7 @@ static int mmsh_open_internal(URLContext *h, const char *uri, int flags, int tim
goto fail;
}
av_dlog(NULL, "out_buffer is %s", headers);
- ff_http_set_headers(mms->mms_hd, headers);
+ av_opt_set(mms->mms_hd->priv_data, "headers", headers, 0);
err = ffurl_connect(mms->mms_hd);
if (err) {
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index c53b728271..68083ae2ac 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -1462,7 +1462,7 @@ redirect:
"Pragma: no-cache\r\n"
"Cache-Control: no-cache\r\n",
sessioncookie);
- ff_http_set_headers(rt->rtsp_hd, headers);
+ av_opt_set(rt->rtsp_hd->priv_data, "headers", headers, 0);
/* complete the connection */
if (ffurl_connect(rt->rtsp_hd)) {
@@ -1485,8 +1485,8 @@ redirect:
"Content-Length: 32767\r\n"
"Expires: Sun, 9 Jan 1972 00:00:00 GMT\r\n",
sessioncookie);
- ff_http_set_headers(rt->rtsp_hd_out, headers);
- av_opt_set(rt->rtsp_hd_out->priv_data, "chunksize", "-1", 0);
+ av_opt_set(rt->rtsp_hd_out->priv_data, "headers", headers, 0);
+ av_opt_set(rt->rtsp_hd_out->priv_data, "chunked_post", "0", 0);
/* Initialize the authentication state for the POST session. The HTTP
* protocol implementation doesn't properly handle multi-pass
diff --git a/libavformat/tls.c b/libavformat/tls.c
index bd73febd4d..8211e88846 100644
--- a/libavformat/tls.c
+++ b/libavformat/tls.c
@@ -73,7 +73,7 @@ static int do_tls_poll(URLContext *h, int ret)
struct pollfd p = { c->fd, 0, 0 };
#if CONFIG_GNUTLS
if (ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED) {
- av_log(NULL, AV_LOG_ERROR, "%s\n", gnutls_strerror(ret));
+ av_log(h, AV_LOG_ERROR, "%s\n", gnutls_strerror(ret));
return AVERROR(EIO);
}
if (gnutls_record_get_direction(c->session))
@@ -87,11 +87,11 @@ static int do_tls_poll(URLContext *h, int ret)
} else if (ret == SSL_ERROR_WANT_WRITE) {
p.events = POLLOUT;
} else {
- av_log(NULL, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
+ av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
return AVERROR(EIO);
}
#endif
- if (h->flags & URL_FLAG_NONBLOCK)
+ if (h->flags & AVIO_FLAG_NONBLOCK)
return AVERROR(EAGAIN);
while (1) {
int n = poll(&p, 1, 100);
@@ -148,13 +148,13 @@ static int tls_open(URLContext *h, const char *uri, int flags)
#elif CONFIG_OPENSSL
c->ctx = SSL_CTX_new(SSLv3_client_method());
if (!c->ctx) {
- av_log(NULL, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
+ av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
ret = AVERROR(EIO);
goto fail;
}
c->ssl = SSL_new(c->ctx);
if (!c->ssl) {
- av_log(NULL, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
+ av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
ret = AVERROR(EIO);
goto fail;
}
@@ -166,7 +166,7 @@ static int tls_open(URLContext *h, const char *uri, int flags)
if (ret > 0)
break;
if (ret == 0) {
- av_log(NULL, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
+ av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
ret = AVERROR(EIO);
goto fail;
}