diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-11-11 02:32:38 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-11-11 02:50:35 +0100 |
commit | 6d91045d835635fe889f684bdf77f68e00b15d0b (patch) | |
tree | ad30db96b3ae0e94efbb8878e0850bd2945bdaf6 /libavformat | |
parent | 554caed2d397e137286f2cc71c6bac477b41fa96 (diff) | |
parent | 299809defb05eae093cb72da97dfbbb7e17e08fe (diff) | |
download | ffmpeg-6d91045d835635fe889f684bdf77f68e00b15d0b.tar.gz |
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.c | 29 | ||||
-rw-r--r-- | libavformat/avio.c | 5 | ||||
-rw-r--r-- | libavformat/crypto.c | 12 | ||||
-rw-r--r-- | libavformat/http.c | 56 | ||||
-rw-r--r-- | libavformat/http.h | 18 | ||||
-rw-r--r-- | libavformat/mmsh.c | 5 | ||||
-rw-r--r-- | libavformat/rtsp.c | 6 | ||||
-rw-r--r-- | libavformat/tls.c | 12 |
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; } |