From 12348ca25e0bf44bf4530745753e938fc54e7ae3 Mon Sep 17 00:00:00 2001 From: John Brooks Date: Thu, 17 Nov 2011 08:50:12 -0700 Subject: [PATCH 01/22] rtpdec: unwrap RTP timestamps for PTS calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The timestamp field in RTPDemuxContext was unused before this. Signed-off-by: Martin Storsjö --- libavformat/rtpdec.c | 8 +++++++- libavformat/rtpdec.h | 1 + libavformat/rtspdec.c | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c index a5ec1caf7a..94fa0f102b 100644 --- a/libavformat/rtpdec.c +++ b/libavformat/rtpdec.c @@ -439,7 +439,13 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam if (!s->base_timestamp) s->base_timestamp = timestamp; - pkt->pts = s->range_start_offset + timestamp - s->base_timestamp; + /* assume that the difference is INT32_MIN < x < INT32_MAX, but allow the first timestamp to exceed INT32_MAX */ + if (!s->timestamp) + s->unwrapped_timestamp += timestamp; + else + s->unwrapped_timestamp += (int32_t)(timestamp - s->timestamp); + s->timestamp = timestamp; + pkt->pts = s->unwrapped_timestamp + s->range_start_offset - s->base_timestamp; } static int rtp_parse_packet_internal(RTPDemuxContext *s, AVPacket *pkt, diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h index d58edddf41..eb1e62daec 100644 --- a/libavformat/rtpdec.h +++ b/libavformat/rtpdec.h @@ -151,6 +151,7 @@ struct RTPDemuxContext { uint32_t timestamp; uint32_t base_timestamp; uint32_t cur_timestamp; + int64_t unwrapped_timestamp; int64_t range_start_offset; int max_payload_size; struct MpegTSContext *ts; /* only used for MP2T payloads */ diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c index c453b82195..1b4982f212 100644 --- a/libavformat/rtspdec.c +++ b/libavformat/rtspdec.c @@ -52,6 +52,8 @@ static int rtsp_read_play(AVFormatContext *s) rtpctx->last_rtcp_ntp_time = AV_NOPTS_VALUE; rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE; rtpctx->base_timestamp = 0; + rtpctx->timestamp = 0; + rtpctx->unwrapped_timestamp = 0; rtpctx->rtcp_ts_offset = 0; } } From 525c5b08fb835cad000810d6299964f300a17daa Mon Sep 17 00:00:00 2001 From: John Brooks Date: Wed, 9 Nov 2011 16:28:35 -0700 Subject: [PATCH 02/22] rtpdec: only use RTCP for PTS when synchronizing multiple streams MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RTCP timestamps are only necessary to synchronize time between multiple streams. For a single stream, the RTP packet timestamp provides more reliable timing. As a result, single-stream RTP sessions should now have accurate and monotonic PTS. Signed-off-by: Martin Storsjö --- libavformat/rtpdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c index 94fa0f102b..88cf15bdea 100644 --- a/libavformat/rtpdec.c +++ b/libavformat/rtpdec.c @@ -424,7 +424,7 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam if (timestamp == RTP_NOTS_VALUE) return; - if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) { + if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE && s->ic->nb_streams > 1) { int64_t addend; int delta_timestamp; From ddf9b510e772fb723ba8cb487ca000dd91b3d1f7 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Mon, 14 Nov 2011 20:08:50 -0500 Subject: [PATCH 03/22] segafilm: add support for raw videos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/segafilm.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c index d4e496582b..b75c8774ce 100644 --- a/libavformat/segafilm.c +++ b/libavformat/segafilm.c @@ -34,6 +34,7 @@ #define FDSC_TAG MKBETAG('F', 'D', 'S', 'C') #define STAB_TAG MKBETAG('S', 'T', 'A', 'B') #define CVID_TAG MKBETAG('c', 'v', 'i', 'd') +#define RAW_TAG MKBETAG('r', 'a', 'w', ' ') typedef struct { int stream; @@ -129,8 +130,11 @@ static int film_read_header(AVFormatContext *s, if (AV_RB32(&scratch[8]) == CVID_TAG) { film->video_type = CODEC_ID_CINEPAK; - } else + } else if (AV_RB32(&scratch[8]) == RAW_TAG) { + film->video_type = CODEC_ID_RAWVIDEO; + } else { film->video_type = CODEC_ID_NONE; + } /* initialize the decoder streams */ if (film->video_type) { @@ -143,6 +147,15 @@ static int film_read_header(AVFormatContext *s, st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = AV_RB32(&scratch[16]); st->codec->height = AV_RB32(&scratch[12]); + + if (film->video_type == CODEC_ID_RAWVIDEO) { + if (scratch[20] == 24) { + st->codec->pix_fmt = PIX_FMT_RGB24; + } else { + av_log(s, AV_LOG_ERROR, "raw video is using unhandled %dbpp\n", scratch[20]); + return -1; + } + } } if (film->audio_type) { From bf7723a6407b6dfced80b8e90fcbc52901389274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 10 Nov 2011 14:52:50 +0200 Subject: [PATCH 04/22] http: Split out the non-chunked buffer reading part from http_read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is in preparation for a later commit, where this function is reused. Signed-off-by: Martin Storsjö --- libavformat/http.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index 9cc55bd3fc..d5bf96bf7a 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -413,10 +413,33 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, } -static int http_read(URLContext *h, uint8_t *buf, int size) +static int http_buf_read(URLContext *h, uint8_t *buf, int size) { HTTPContext *s = h->priv_data; int len; + /* read bytes from input buffer first */ + len = s->buf_end - s->buf_ptr; + if (len > 0) { + if (len > size) + len = size; + memcpy(buf, s->buf_ptr, len); + s->buf_ptr += len; + } else { + if (!s->willclose && s->filesize >= 0 && s->off >= s->filesize) + return AVERROR_EOF; + len = ffurl_read(s->hd, buf, size); + } + if (len > 0) { + s->off += len; + if (s->chunksize > 0) + s->chunksize -= len; + } + return len; +} + +static int http_read(URLContext *h, uint8_t *buf, int size) +{ + HTTPContext *s = h->priv_data; if (s->chunksize >= 0) { if (!s->chunksize) { @@ -439,24 +462,7 @@ static int http_read(URLContext *h, uint8_t *buf, int size) } size = FFMIN(size, s->chunksize); } - /* read bytes from input buffer first */ - len = s->buf_end - s->buf_ptr; - if (len > 0) { - if (len > size) - len = size; - memcpy(buf, s->buf_ptr, len); - s->buf_ptr += len; - } else { - if (!s->willclose && s->filesize >= 0 && s->off >= s->filesize) - return AVERROR_EOF; - len = ffurl_read(s->hd, buf, size); - } - if (len > 0) { - s->off += len; - if (s->chunksize > 0) - s->chunksize -= len; - } - return len; + return http_buf_read(h, buf, size); } /* used only when posting data */ From 9f1dae944e2cf72800eb79b32e831b59fd6afdb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 10 Nov 2011 14:53:16 +0200 Subject: [PATCH 05/22] http: Add a new protocol for opening connections via http proxies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This opens a plain TCP connection through the proxy via the CONNECT HTTP method. Normally, this is allowed for connections on port 443, but can in general be used to allow connections to any port (depending on proxy configuration), and could thus be used to tunnel any TCP connection via a HTTP proxy. Signed-off-by: Martin Storsjö --- libavformat/allformats.c | 1 + libavformat/http.c | 115 +++++++++++++++++++++++++++++++++++++++ libavformat/version.h | 2 +- 3 files changed, 117 insertions(+), 1 deletion(-) diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 00924c8a11..bee2f5f11f 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -242,6 +242,7 @@ void av_register_all(void) REGISTER_PROTOCOL (FILE, file); REGISTER_PROTOCOL (GOPHER, gopher); REGISTER_PROTOCOL (HTTP, http); + REGISTER_PROTOCOL (HTTPPROXY, httpproxy); REGISTER_PROTOCOL (HTTPS, https); REGISTER_PROTOCOL (MMSH, mmsh); REGISTER_PROTOCOL (MMST, mmst); diff --git a/libavformat/http.c b/libavformat/http.c index d5bf96bf7a..5941925118 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -578,3 +578,118 @@ URLProtocol ff_https_protocol = { .priv_data_class = &https_context_class, }; #endif + +#if CONFIG_HTTPPROXY_PROTOCOL +static int http_proxy_close(URLContext *h) +{ + HTTPContext *s = h->priv_data; + if (s->hd) + ffurl_close(s->hd); + return 0; +} + +static int http_proxy_open(URLContext *h, const char *uri, int flags) +{ + HTTPContext *s = h->priv_data; + char hostname[1024], hoststr[1024]; + char auth[1024], pathbuf[1024], *path; + char line[1024], lower_url[100]; + int port, ret = 0; + HTTPAuthType cur_auth_type; + char *authstr; + + h->is_streamed = 1; + + av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port, + pathbuf, sizeof(pathbuf), uri); + ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); + path = pathbuf; + if (*path == '/') + path++; + + ff_url_join(lower_url, sizeof(lower_url), "tcp", NULL, hostname, port, + NULL); +redo: + ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE, + &h->interrupt_callback, NULL); + if (ret < 0) + return ret; + + authstr = ff_http_auth_create_response(&s->proxy_auth_state, auth, + path, "CONNECT"); + snprintf(s->buffer, sizeof(s->buffer), + "CONNECT %s HTTP/1.1\r\n" + "Host: %s\r\n" + "Connection: close\r\n" + "%s%s" + "\r\n", + path, + hoststr, + authstr ? "Proxy-" : "", authstr ? authstr : ""); + av_freep(&authstr); + + if ((ret = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0) + goto fail; + + s->buf_ptr = s->buffer; + s->buf_end = s->buffer; + s->line_count = 0; + s->filesize = -1; + cur_auth_type = s->proxy_auth_state.auth_type; + + for (;;) { + int new_loc; + // Note: This uses buffering, potentially reading more than the + // HTTP header. If tunneling a protocol where the server starts + // the conversation, we might buffer part of that here, too. + // Reading that requires using the proper ffurl_read() function + // on this URLContext, not using the fd directly (as the tls + // protocol does). This shouldn't be an issue for tls though, + // since the client starts the conversation there, so there + // is no extra data that we might buffer up here. + if (http_get_line(s, line, sizeof(line)) < 0) { + ret = AVERROR(EIO); + goto fail; + } + + av_dlog(h, "header='%s'\n", line); + + ret = process_line(h, line, s->line_count, &new_loc); + if (ret < 0) + goto fail; + if (ret == 0) + break; + s->line_count++; + } + if (s->http_code == 407 && cur_auth_type == HTTP_AUTH_NONE && + s->proxy_auth_state.auth_type != HTTP_AUTH_NONE) { + ffurl_close(s->hd); + s->hd = NULL; + goto redo; + } + + if (s->http_code < 400) + return 0; + ret = AVERROR(EIO); + +fail: + http_proxy_close(h); + return ret; +} + +static int http_proxy_write(URLContext *h, const uint8_t *buf, int size) +{ + HTTPContext *s = h->priv_data; + return ffurl_write(s->hd, buf, size); +} + +URLProtocol ff_httpproxy_protocol = { + .name = "httpproxy", + .url_open = http_proxy_open, + .url_read = http_buf_read, + .url_write = http_proxy_write, + .url_close = http_proxy_close, + .url_get_file_handle = http_get_file_handle, + .priv_data_size = sizeof(HTTPContext), +}; +#endif diff --git a/libavformat/version.h b/libavformat/version.h index ec5d1fda03..6c1db42d21 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -24,7 +24,7 @@ #include "libavutil/avutil.h" #define LIBAVFORMAT_VERSION_MAJOR 53 -#define LIBAVFORMAT_VERSION_MINOR 14 +#define LIBAVFORMAT_VERSION_MINOR 15 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ From f5c5d57b57ba74be4d8475d729675e464ed4ecb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 10 Nov 2011 14:55:18 +0200 Subject: [PATCH 06/22] http: Reorder two code blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is in preparation for a later commit. Signed-off-by: Martin Storsjö --- libavformat/http.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index 5941925118..45253d4efd 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -110,6 +110,14 @@ static int http_open_cnx(URLContext *h) path1, sizeof(path1), s->location); ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); + if (!strcmp(proto, "https")) { + lower_proto = "tls"; + if (port < 0) + port = 443; + } + if (port < 0) + port = 80; + if (path1[0] == '\0') path = "/"; else @@ -124,13 +132,6 @@ static int http_open_cnx(URLContext *h) av_url_split(NULL, 0, proxyauth, sizeof(proxyauth), hostname, sizeof(hostname), &port, NULL, 0, proxy_path); } - if (!strcmp(proto, "https")) { - lower_proto = "tls"; - if (port < 0) - port = 443; - } - if (port < 0) - port = 80; ff_url_join(buf, sizeof(buf), lower_proto, NULL, hostname, port, NULL); err = ffurl_open(&hd, buf, AVIO_FLAG_READ_WRITE, From 2565dbeb3e36e4f2d7970aa756c6ac40b7f46914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 10 Nov 2011 15:26:23 +0200 Subject: [PATCH 07/22] tls: Handle connection via a http proxy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/tls.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/libavformat/tls.c b/libavformat/tls.c index 72c2b85016..339b799322 100644 --- a/libavformat/tls.c +++ b/libavformat/tls.c @@ -111,9 +111,15 @@ static int tls_open(URLContext *h, const char *uri, int flags) char buf[200], host[200]; int numerichost = 0; struct addrinfo hints = { 0 }, *ai = NULL; + const char *proxy_path; + int use_proxy; ff_tls_init(); + proxy_path = getenv("http_proxy"); + use_proxy = (proxy_path != NULL) && !getenv("no_proxy") && + av_strstart(proxy_path, "http://", NULL); + av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0, uri); ff_url_join(buf, sizeof(buf), "tcp", NULL, host, port, NULL); @@ -123,6 +129,17 @@ static int tls_open(URLContext *h, const char *uri, int flags) freeaddrinfo(ai); } + if (use_proxy) { + char proxy_host[200], proxy_auth[200], dest[200]; + int proxy_port; + av_url_split(NULL, 0, proxy_auth, sizeof(proxy_auth), + proxy_host, sizeof(proxy_host), &proxy_port, NULL, 0, + proxy_path); + ff_url_join(dest, sizeof(dest), NULL, NULL, host, port, NULL); + ff_url_join(buf, sizeof(buf), "httpproxy", proxy_auth, proxy_host, + proxy_port, "/%s", dest); + } + ret = ffurl_open(&c->tcp, buf, AVIO_FLAG_READ_WRITE, &h->interrupt_callback, NULL); if (ret) From dbc2424baa5aa4c72026d167f0678f2374620f44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 10 Nov 2011 14:57:15 +0200 Subject: [PATCH 08/22] http: Don't use the normal http proxy mechanism for https MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tls protocol handles connections via proxies internally. With TLS/SSL, the peer verification requires that the client speaks directly with the server, since the proxy doesn't have the remote server's private key. Signed-off-by: Martin Storsjö --- libavformat/http.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/http.c b/libavformat/http.c index 45253d4efd..63cfecd332 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -112,6 +112,7 @@ static int http_open_cnx(URLContext *h) if (!strcmp(proto, "https")) { lower_proto = "tls"; + use_proxy = 0; if (port < 0) port = 443; } From 795d9594cfaf9b6c9ce0c60f86c6e51636096a5a Mon Sep 17 00:00:00 2001 From: "Panagiotis H.M. Issaris" Date: Tue, 15 Nov 2011 18:35:03 +0100 Subject: [PATCH 09/22] applehttp: Fix seeking in streams not starting at DTS=0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Apple HTTP Live Streaming demuxer's implementation of seeking searches for the MPEG TS segment which contains the requested timestamp. In its current implementation it assumes that the first segment will start from 0. But, MPEG TS streams do not necessarily start with timestamp (near) 0, causing seeking to fail for those streams. This also occurs when using live streaming of HTTP Live Streams. In this case sliding playlists may be used, which means that in that case only the last x encoded segments are stored, the earlier segments get deleted from disk and removed from the playlist. Because of this, when starting playback of a stream in the middle of such a broadcast, the initial segment fetched after parsing the m3u8 playlist will not start from timestamp (near) 0, causing (the admittedly limited live) seeking to fail. This patch changes this demuxers seeking implementation to use the initial DTS as an offset for searching the segments containing the requested timestamp. Signed-off-by: Martin Storsjö --- libavformat/applehttp.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c index e0773ae87f..366d8327ff 100644 --- a/libavformat/applehttp.c +++ b/libavformat/applehttp.c @@ -99,6 +99,7 @@ typedef struct AppleHTTPContext { int cur_seq_no; int end_of_segment; int first_packet; + int64_t first_timestamp; AVIOInterruptCB *interrupt_callback; } AppleHTTPContext; @@ -527,6 +528,7 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap) } c->first_packet = 1; + c->first_timestamp = AV_NOPTS_VALUE; return 0; fail: @@ -591,6 +593,9 @@ start: if (!var->pb.eof_reached) return ret; reset_packet(&var->pkt); + } else { + if (c->first_timestamp == AV_NOPTS_VALUE) + c->first_timestamp = var->pkt.dts; } } /* Check if this stream has the packet with the lowest dts */ @@ -639,7 +644,10 @@ static int applehttp_read_seek(AVFormatContext *s, int stream_index, for (i = 0; i < c->n_variants; i++) { /* Reset reading */ struct variant *var = c->variants[i]; - int64_t pos = 0; + int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? 0 : + av_rescale_rnd(c->first_timestamp, 1, + stream_index >= 0 ? s->streams[stream_index]->time_base.den : AV_TIME_BASE, + flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP); if (var->input) { ffurl_close(var->input); var->input = NULL; From b55aa7df6b79746541f05d65c414961f49f46f68 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 16 Nov 2011 15:10:26 +0100 Subject: [PATCH 10/22] cinepak: Fix division by zero, ask for sample if encoded_buf_size is 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michael Niedermayer Signed-off-by: Martin Storsjö --- libavcodec/cinepak.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c index f8b5352e35..0dbdeab354 100644 --- a/libavcodec/cinepak.c +++ b/libavcodec/cinepak.c @@ -330,6 +330,10 @@ static int cinepak_decode (CinepakContext *s) /* if this is the first frame, check for deviant Sega FILM data */ if (s->sega_film_skip_bytes == -1) { + if (!encoded_buf_size) { + av_log_ask_for_sample(s->avctx, "encoded_buf_size is 0"); + return -1; + } if (encoded_buf_size != s->size && (s->size % encoded_buf_size) != 0) { /* If the encoded frame size differs from the frame size as indicated * by the container file, this data likely comes from a Sega FILM/CPK file. From a2b51fe87c49c3ce21c4ae3310be234a9f87795c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 16 Nov 2011 17:15:15 +0100 Subject: [PATCH 11/22] cinepak: simplify, use FFMIN() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michael Niedermayer Signed-off-by: Martin Storsjö --- libavcodec/cinepak.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c index 0dbdeab354..c6edfe6cc9 100644 --- a/libavcodec/cinepak.c +++ b/libavcodec/cinepak.c @@ -357,8 +357,7 @@ static int cinepak_decode (CinepakContext *s) s->data += 10 + s->sega_film_skip_bytes; - if (num_strips > MAX_STRIPS) - num_strips = MAX_STRIPS; + num_strips = FFMIN(num_strips, MAX_STRIPS); for (i=0; i < num_strips; i++) { if ((s->data + 12) > eod) From d92fea2b1420aea1c1f3c2ececbd953f5f06f49b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 16 Nov 2011 17:16:38 +0100 Subject: [PATCH 12/22] cinepak, simplify, use AV_RB24() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michael Niedermayer Signed-off-by: Martin Storsjö --- libavcodec/cinepak.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c index c6edfe6cc9..e66a1c05a2 100644 --- a/libavcodec/cinepak.c +++ b/libavcodec/cinepak.c @@ -326,7 +326,7 @@ static int cinepak_decode (CinepakContext *s) frame_flags = s->data[0]; num_strips = AV_RB16 (&s->data[8]); - encoded_buf_size = ((s->data[1] << 16) | AV_RB16 (&s->data[2])); + encoded_buf_size = AV_RB24(&s->data[1]); /* if this is the first frame, check for deviant Sega FILM data */ if (s->sega_film_skip_bytes == -1) { From 867b496681b3cdc774b80764fbea42f7c9aca842 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 16 Nov 2011 17:21:42 +0100 Subject: [PATCH 13/22] cinepak: check strip_size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michael Niedermayer Signed-off-by: Martin Storsjö --- libavcodec/cinepak.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c index e66a1c05a2..a858d6e866 100644 --- a/libavcodec/cinepak.c +++ b/libavcodec/cinepak.c @@ -370,6 +370,8 @@ static int cinepak_decode (CinepakContext *s) s->strips[i].x2 = s->avctx->width; strip_size = AV_RB24 (&s->data[1]) - 12; + if (strip_size < 0) + return -1; s->data += 12; strip_size = ((s->data + strip_size) > eod) ? (eod - s->data) : strip_size; From a4009c6a9adc9ea38eb56967b6a5e933451ae545 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 16 Nov 2011 17:25:39 +0100 Subject: [PATCH 14/22] cinepak: remove redundant coordinate checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michael Niedermayer Signed-off-by: Martin Storsjö --- libavcodec/cinepak.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c index a858d6e866..8ae1bb3f2b 100644 --- a/libavcodec/cinepak.c +++ b/libavcodec/cinepak.c @@ -269,8 +269,8 @@ static int cinepak_decode_strip (CinepakContext *s, int chunk_id, chunk_size; /* coordinate sanity checks */ - if (strip->x1 >= s->width || strip->x2 > s->width || - strip->y1 >= s->height || strip->y2 > s->height || + if (strip->x2 > s->width || + strip->y2 > s->height || strip->x1 >= strip->x2 || strip->y1 >= strip->y2) return -1; From 2abe947ac0be328a1d9f47562afffdcba055bc74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 6 Nov 2011 23:22:04 +0200 Subject: [PATCH 15/22] avconv: Set new interrupt callbacks for all AVFormatContexts, use avio_open2() everywhere Signed-off-by: Anton Khirnov --- avconv.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/avconv.c b/avconv.c index eb7df9afac..ef41245726 100644 --- a/avconv.c +++ b/avconv.c @@ -503,11 +503,13 @@ static void term_init(void) #endif } -static int decode_interrupt_cb(void) +static int decode_interrupt_cb(void *ctx) { return received_nb_signals > 1; } +static const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL }; + void exit_program(int ret) { int i; @@ -2272,6 +2274,7 @@ static int transcode_init(OutputFile *output_files, /* open files and write file headers */ for (i = 0; i < nb_output_files; i++) { os = output_files[i].ctx; + os->interrupt_callback = int_cb; if (avformat_write_header(os, &output_files[i].opts) < 0) { snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i); ret = AVERROR(EINVAL); @@ -2887,7 +2890,7 @@ static void dump_attachment(AVStream *st, const char *filename) assert_file_overwrite(filename); - if ((ret = avio_open (&out, filename, AVIO_FLAG_WRITE)) < 0) { + if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) { av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n", filename); exit_program(1); @@ -2945,6 +2948,7 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena av_dict_set(&format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0); ic->flags |= AVFMT_FLAG_NONBLOCK; + ic->interrupt_callback = int_cb; /* open the input file with generic libav function */ err = avformat_open_input(&ic, filename, file_iformat, &format_opts); @@ -3074,12 +3078,12 @@ static int get_preset_file_2(const char *preset_name, const char *codec_name, AV if (codec_name) { snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i], i != 1 ? "" : "/.avconv", codec_name, preset_name); - ret = avio_open(s, filename, AVIO_FLAG_READ); + ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL); } if (ret) { snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i], i != 1 ? "" : "/.avconv", preset_name); - ret = avio_open(s, filename, AVIO_FLAG_READ); + ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL); } } return ret; @@ -3465,8 +3469,9 @@ static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata) static int read_avserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename) { int i, err; - AVFormatContext *ic = NULL; + AVFormatContext *ic = avformat_alloc_context(); + ic->interrupt_callback = int_cb; err = avformat_open_input(&ic, filename, NULL, NULL); if (err < 0) return err; @@ -3529,6 +3534,7 @@ static void opt_output_file(void *optctx, const char *filename) } oc->oformat = file_oformat; + oc->interrupt_callback = int_cb; av_strlcpy(oc->filename, filename, sizeof(oc->filename)); if (!strcmp(file_oformat->name, "ffm") && @@ -3621,7 +3627,7 @@ static void opt_output_file(void *optctx, const char *filename) const char *p; int64_t len; - if ((err = avio_open(&pb, o->attachments[i], AVIO_FLAG_READ)) < 0) { + if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) { av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n", o->attachments[i]); exit_program(1); @@ -3671,7 +3677,9 @@ static void opt_output_file(void *optctx, const char *filename) assert_file_overwrite(filename); /* open the file */ - if ((err = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) { + if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE, + &oc->interrupt_callback, + &output_files[nb_output_files - 1].opts)) < 0) { print_error(filename, err); exit_program(1); } @@ -4219,8 +4227,6 @@ int main(int argc, char **argv) av_register_all(); avformat_network_init(); - avio_set_interrupt_cb(decode_interrupt_cb); - show_banner(); /* parse options */ From 40972f7c54e013d2da8bf42cb34ab25cfea75eab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 6 Nov 2011 23:28:49 +0200 Subject: [PATCH 16/22] avplay: Set the new interrupt callback Signed-off-by: Anton Khirnov --- avplay.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/avplay.c b/avplay.c index 01c0f118e9..556c463aec 100644 --- a/avplay.c +++ b/avplay.c @@ -2339,7 +2339,7 @@ static void stream_component_close(VideoState *is, int stream_index) variable instead of a thread local variable */ static VideoState *global_video_state; -static int decode_interrupt_cb(void) +static int decode_interrupt_cb(void *ctx) { return (global_video_state && global_video_state->abort_request); } @@ -2364,8 +2364,9 @@ static int decode_thread(void *arg) is->subtitle_stream = -1; global_video_state = is; - avio_set_interrupt_cb(decode_interrupt_cb); + ic = avformat_alloc_context(); + ic->interrupt_callback.callback = decode_interrupt_cb; err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts); if (err < 0) { print_error(is->filename, err); From 45f511ece7aaf730d51dff5b086e32bc43fc78ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 7 Nov 2011 12:17:50 +0200 Subject: [PATCH 17/22] avio: Mark the old interrupt callback mechanism as deprecated Prepare for removing it at an upcoming major bump. --- libavformat/avio.c | 10 +++++++++- libavformat/avio.h | 6 +++++- libavformat/version.h | 3 +++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/libavformat/avio.c b/libavformat/avio.c index 9de435e073..4750a9d544 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -83,9 +83,11 @@ const AVClass ffurl_context_class = { }; /*@}*/ -static int default_interrupt_cb(void); +#if FF_API_OLD_INTERRUPT_CB +static int default_interrupt_cb(void); int (*url_interrupt_cb)(void) = default_interrupt_cb; +#endif #if FF_API_OLD_AVIO URLProtocol *av_protocol_next(URLProtocol *p) @@ -441,6 +443,7 @@ int ffurl_get_file_handle(URLContext *h) return h->prot->url_get_file_handle(h); } +#if FF_API_OLD_INTERRUPT_CB static int default_interrupt_cb(void) { return 0; @@ -452,13 +455,18 @@ void avio_set_interrupt_cb(int (*interrupt_cb)(void)) interrupt_cb = default_interrupt_cb; url_interrupt_cb = interrupt_cb; } +#endif int ff_check_interrupt(AVIOInterruptCB *cb) { int ret; if (cb && cb->callback && (ret = cb->callback(cb->opaque))) return ret; +#if FF_API_OLD_INTERRUPT_CB return url_interrupt_cb(); +#else + return 0; +#endif } #if FF_API_OLD_AVIO diff --git a/libavformat/avio.h b/libavformat/avio.h index b665bb3b3b..d7977022bf 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -389,13 +389,17 @@ attribute_deprecated int url_exist(const char *url); */ int avio_check(const char *url, int flags); +#if FF_API_OLD_INTERRUPT_CB /** * The callback is called in blocking functions to test regulary if * asynchronous interruption is needed. AVERROR_EXIT is returned * in this case by the interrupted function. 'NULL' means no interrupt * callback is given. + * @deprecated Use interrupt_callback in AVFormatContext/avio_open2 + * instead. */ -void avio_set_interrupt_cb(int (*interrupt_cb)(void)); +attribute_deprecated void avio_set_interrupt_cb(int (*interrupt_cb)(void)); +#endif /** * Allocate and initialize an AVIOContext for buffered I/O. It must be later diff --git a/libavformat/version.h b/libavformat/version.h index 6c1db42d21..d56bdb7c87 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -110,5 +110,8 @@ #ifndef FF_API_REORDER_PRIVATE #define FF_API_REORDER_PRIVATE (LIBAVFORMAT_VERSION_MAJOR < 54) #endif +#ifndef FF_API_OLD_INTERRUPT_CB +#define FF_API_OLD_INTERRUPT_CB (LIBAVFORMAT_VERSION_MAJOR < 54) +#endif #endif /* AVFORMAT_VERSION_H */ From f872e4d0a76abd1c99bf9ad6efabc3816944c9bb Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 13 Nov 2011 17:08:26 +0100 Subject: [PATCH 18/22] Add an APIchanges entry and a minor bump for avio changes. --- doc/APIchanges | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/APIchanges b/doc/APIchanges index c45aca62a2..f1913bd6de 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,16 @@ libavutil: 2011-04-18 API changes, most recent first: +2011-11-13 - lavf 53.15.0 + New interrupt callback API, allowing per-AVFormatContext/AVIOContext + interrupt callbacks. + 6aa0b98 Add AVIOInterruptCB struct and the interrupt_callback field to + AVFormatContext. + 1dee0ac Add avio_open2() with additional parameters. Those are + an interrupt callback and an options AVDictionary. + This will allow passing AVOptions to protocols after lavf + 54.0. + 2011-11-xx - xxxxxxx - lavu 51.16.0 Add av_timegm() From 81ac4cda0b00296c8eb41d930bdecce696cfafa6 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 14 Nov 2011 09:11:26 +0100 Subject: [PATCH 19/22] fate-lavf-ts: use -mpegts_transport_stream_id option. Serves as a test of muxer private options. --- tests/lavf-regression.sh | 2 +- tests/ref/lavf/ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh index 7cd9f7f909..4a72e0ac1c 100755 --- a/tests/lavf-regression.sh +++ b/tests/lavf-regression.sh @@ -71,7 +71,7 @@ do_lavf mxf_d10 "-ar 48000 -ac 2 -r 25 -s 720x576 -vf pad=720:608:0:32 -vcodec m fi if [ -n "$do_ts" ] ; then -do_lavf ts +do_lavf ts "-mpegts_transport_stream_id 42" fi if [ -n "$do_swf" ] ; then diff --git a/tests/ref/lavf/ts b/tests/ref/lavf/ts index 325112cebc..ebe6a77566 100644 --- a/tests/ref/lavf/ts +++ b/tests/ref/lavf/ts @@ -1,3 +1,3 @@ -9708011dd80212a0041a96da878122c2 *./tests/data/lavf/lavf.ts +293142d7286db15e5f4d7d1ca0d9c97c *./tests/data/lavf/lavf.ts 406644 ./tests/data/lavf/lavf.ts ./tests/data/lavf/lavf.ts CRC=0x133216c1 From b7d939d9986fa636bf7b78ac51945f51999c678c Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Fri, 18 Nov 2011 12:10:41 +0100 Subject: [PATCH 20/22] cinepack: return non-generic errors --- libavcodec/cinepak.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c index 8ae1bb3f2b..9cf38edb8e 100644 --- a/libavcodec/cinepak.c +++ b/libavcodec/cinepak.c @@ -147,7 +147,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip, for (x=strip->x1; x < strip->x2; x+=4) { if ((chunk_id & 0x01) && !(mask >>= 1)) { if ((data + 4) > eod) - return -1; + return AVERROR_INVALIDDATA; flag = AV_RB32 (data); data += 4; @@ -157,7 +157,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip, if (!(chunk_id & 0x01) || (flag & mask)) { if (!(chunk_id & 0x02) && !(mask >>= 1)) { if ((data + 4) > eod) - return -1; + return AVERROR_INVALIDDATA; flag = AV_RB32 (data); data += 4; @@ -166,7 +166,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip, if ((chunk_id & 0x02) || (~flag & mask)) { if (data >= eod) - return -1; + return AVERROR_INVALIDDATA; codebook = &strip->v1_codebook[*data++]; s->frame.data[0][iy[0] + 0] = codebook->y0; @@ -207,7 +207,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip, } else if (flag & mask) { if ((data + 4) > eod) - return -1; + return AVERROR_INVALIDDATA; codebook = &strip->v4_codebook[*data++]; s->frame.data[0][iy[0] + 0] = codebook->y0; @@ -272,13 +272,13 @@ static int cinepak_decode_strip (CinepakContext *s, if (strip->x2 > s->width || strip->y2 > s->height || strip->x1 >= strip->x2 || strip->y1 >= strip->y2) - return -1; + return AVERROR_INVALIDDATA; while ((data + 4) <= eod) { chunk_id = data[0]; chunk_size = AV_RB24 (&data[1]) - 4; if(chunk_size < 0) - return -1; + return AVERROR_INVALIDDATA; data += 4; chunk_size = ((data + chunk_size) > eod) ? (eod - data) : chunk_size; @@ -311,7 +311,7 @@ static int cinepak_decode_strip (CinepakContext *s, data += chunk_size; } - return -1; + return AVERROR_INVALIDDATA; } static int cinepak_decode (CinepakContext *s) @@ -322,7 +322,7 @@ static int cinepak_decode (CinepakContext *s) int encoded_buf_size; if (s->size < 10) - return -1; + return AVERROR_INVALIDDATA; frame_flags = s->data[0]; num_strips = AV_RB16 (&s->data[8]); @@ -332,7 +332,7 @@ static int cinepak_decode (CinepakContext *s) if (s->sega_film_skip_bytes == -1) { if (!encoded_buf_size) { av_log_ask_for_sample(s->avctx, "encoded_buf_size is 0"); - return -1; + return AVERROR_INVALIDDATA; } if (encoded_buf_size != s->size && (s->size % encoded_buf_size) != 0) { /* If the encoded frame size differs from the frame size as indicated @@ -361,7 +361,7 @@ static int cinepak_decode (CinepakContext *s) for (i=0; i < num_strips; i++) { if ((s->data + 12) > eod) - return -1; + return AVERROR_INVALIDDATA; s->strips[i].id = s->data[0]; s->strips[i].y1 = y0; @@ -371,7 +371,7 @@ static int cinepak_decode (CinepakContext *s) strip_size = AV_RB24 (&s->data[1]) - 12; if (strip_size < 0) - return -1; + return AVERROR_INVALIDDATA; s->data += 12; strip_size = ((s->data + strip_size) > eod) ? (eod - s->data) : strip_size; @@ -421,7 +421,7 @@ static int cinepak_decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + int ret = 0, buf_size = avpkt->size; CinepakContext *s = avctx->priv_data; s->data = buf; @@ -430,9 +430,9 @@ static int cinepak_decode_frame(AVCodecContext *avctx, s->frame.reference = 1; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, &s->frame)) { + if ((ret = avctx->reget_buffer(avctx, &s->frame))) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; + return ret; } if (s->palette_video) { From 704af3e29c3ddbc22ac5c8f40e5a0f860d53ac4c Mon Sep 17 00:00:00 2001 From: Josh Allmann Date: Sat, 12 Nov 2011 13:28:58 -0800 Subject: [PATCH 21/22] rtmp: do not hardcode invoke numbers Note: FCPublish/FCUnpublish are adobe server specific and not described in the rtmp specification. Some servers might not cope with them at all. Signed-off-by: Luca Barbato --- libavformat/rtmpproto.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 9d734072ab..37c3d95aca 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -74,6 +74,7 @@ typedef struct RTMPContext { int skip_bytes; ///< number of bytes to skip from the input FLV stream in the next write call uint8_t flv_header[11]; ///< partial incoming flv packet header int flv_header_bytes; ///< number of initialized bytes in flv_header + int nb_invokes; ///< keeps track of invoke messages } RTMPContext; #define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing @@ -166,7 +167,7 @@ static void gen_release_stream(URLContext *s, RTMPContext *rt) av_log(s, AV_LOG_DEBUG, "Releasing stream...\n"); p = pkt.data; ff_amf_write_string(&p, "releaseStream"); - ff_amf_write_number(&p, 2.0); + ff_amf_write_number(&p, ++rt->nb_invokes); ff_amf_write_null(&p); ff_amf_write_string(&p, rt->playpath); @@ -189,7 +190,7 @@ static void gen_fcpublish_stream(URLContext *s, RTMPContext *rt) av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n"); p = pkt.data; ff_amf_write_string(&p, "FCPublish"); - ff_amf_write_number(&p, 3.0); + ff_amf_write_number(&p, ++rt->nb_invokes); ff_amf_write_null(&p); ff_amf_write_string(&p, rt->playpath); @@ -212,7 +213,7 @@ static void gen_fcunpublish_stream(URLContext *s, RTMPContext *rt) av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n"); p = pkt.data; ff_amf_write_string(&p, "FCUnpublish"); - ff_amf_write_number(&p, 5.0); + ff_amf_write_number(&p, ++rt->nb_invokes); ff_amf_write_null(&p); ff_amf_write_string(&p, rt->playpath); @@ -234,7 +235,7 @@ static void gen_create_stream(URLContext *s, RTMPContext *rt) p = pkt.data; ff_amf_write_string(&p, "createStream"); - ff_amf_write_number(&p, rt->is_input ? 3.0 : 4.0); + ff_amf_write_number(&p, ++rt->nb_invokes); ff_amf_write_null(&p); ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); From ff3755cbde9bdd2a4dc50e4432f72ddeef1a85ac Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Tue, 1 Nov 2011 20:41:43 +0100 Subject: [PATCH 22/22] configure: add check for w32threads to enable it automatically --- configure | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 6e4259f903..61bb4dfb54 100755 --- a/configure +++ b/configure @@ -2447,7 +2447,6 @@ case $target_os in disable network else target_os=mingw32 - enable_weak w32threads fi LIBTARGET=i386 if enabled x86_64; then @@ -2852,6 +2851,10 @@ check_struct dxva2api.h DXVA_PictureParameters wDecodedPictureIndex disabled zlib || check_lib zlib.h zlibVersion -lz || disable zlib disabled bzlib || check_lib2 bzlib.h BZ2_bzlibVersion -lbz2 || disable bzlib +if ! disabled w32threads && ! enabled pthreads; then + check_func _beginthreadex && enable w32threads +fi + # check for some common methods of building with pthread support # do this before the optional library checks as some of them require pthreads if ! disabled pthreads && ! enabled w32threads; then